apparmor-2.13.3/0000755000175000017500000000000013502024172011205 5ustar jjjjapparmor-2.13.3/utils/0000755000175000017500000000000013502024376012353 5ustar jjjjapparmor-2.13.3/utils/aa-unconfined.80000644000175000017500000001337213502024375015160 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "AA-UNCONFINED 8" .TH AA-UNCONFINED 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa\-unconfined \- output a list of processes with tcp or udp ports that do not have AppArmor profiles loaded .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-unconfined [\f(BI\-\-paranoid\fB] [\f(BI\-\-with\-ss\fB | \f(BI\-\-with\-netstat\fB]\fR .SH "OPTIONS" .IX Header "OPTIONS" .IP "\fB\-\-paranoid\fR" 4 .IX Item "--paranoid" Displays all processes from \fI/proc\fR filesystem with tcp or udp ports that do not have AppArmor profiles loaded. .IP "\fB\-\-with\-ss\fR" 4 .IX Item "--with-ss" Use the \fIss\fR\|(8) command to find processes listening on network sockets (the default). .IP "\fB\-\-with\-netstat\fR" 4 .IX Item "--with-netstat" Use the \fInetstat\fR\|(8) command to find processes listening on network sockets. This is also what aa-unconfined will fall back to when \fIss\fR\|(8) is not available. .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBaa-unconfined\fR will use \fInetstat\fR\|(8) to determine which processes have open network sockets and do not have AppArmor profiles loaded into the kernel. .SH "BUGS" .IX Header "BUGS" \&\fBaa-unconfined\fR must be run as root to retrieve the process executable link from the \fI/proc\fR filesystem. This program is susceptible to race conditions of several flavours: an unlinked executable will be mishandled; an executable started before an AppArmor profile is loaded will not appear in the output, despite running without confinement; a process that dies between the \fInetstat\fR\|(8) and further checks will be mishandled. This program only lists processes using \s-1TCP\s0 and \s-1UDP.\s0 In short, this program is unsuitable for forensics use and is provided only as an aid to profiling all network-accessible processes in the lab. .PP If you find any bugs, please report them at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIss\fR\|(8), \fInetstat\fR\|(8), \fIapparmor\fR\|(7), \fIapparmor.d\fR\|(5), \fIaa_change_hat\fR\|(2), and . apparmor-2.13.3/utils/aa-audit.pod0000644000175000017500000000177213502024172014545 0ustar jjjj=pod =head1 NAME aa-audit - set an AppArmor security profile to I mode. =head1 SYNOPSIS BexecutableE> [IexecutableE> ...] [I<-d /path/to/profiles>] [I<--no-reload>] [I<-r>]> =head1 OPTIONS B<-d --dir /path/to/profiles> Specifies where to look for the AppArmor security profile set. Defaults to /etc/apparmor.d. B<--no-reload> Do not reload the profile after modifying it. B<-r --remove> Removes the audit mode for the profile. =head1 DESCRIPTION B is used to set one or more profiles to audit mode. In this mode security policy is enforced and all access (successes and failures) are logged to the system log. The I<--remove> option can be used to remove the audit mode for the profile. =head1 BUGS If you find any bugs, please report them at L. =head1 SEE ALSO apparmor(7), apparmor.d(5), aa-enforce(1), aa-complain(1), aa-disable(1), aa_change_hat(2), and L. =cut apparmor-2.13.3/utils/apparmor/0000755000175000017500000000000013502024172014166 5ustar jjjjapparmor-2.13.3/utils/apparmor/profile_storage.py0000644000175000017500000001234413502024172017730 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2014-2017 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- from apparmor.common import AppArmorBug, hasher, type_is_str from apparmor.rule.capability import CapabilityRuleset from apparmor.rule.change_profile import ChangeProfileRuleset from apparmor.rule.dbus import DbusRuleset from apparmor.rule.file import FileRuleset from apparmor.rule.network import NetworkRuleset from apparmor.rule.ptrace import PtraceRuleset from apparmor.rule.rlimit import RlimitRuleset from apparmor.rule.signal import SignalRuleset ruletypes = { 'capability': {'ruleset': CapabilityRuleset}, 'change_profile': {'ruleset': ChangeProfileRuleset}, 'dbus': {'ruleset': DbusRuleset}, 'file': {'ruleset': FileRuleset}, 'network': {'ruleset': NetworkRuleset}, 'ptrace': {'ruleset': PtraceRuleset}, 'rlimit': {'ruleset': RlimitRuleset}, 'signal': {'ruleset': SignalRuleset}, } class ProfileStorage: '''class to store the content (header, rules, comments) of a profilename Acts like a dict(), but has some additional checks. ''' def __init__(self, profilename, hat, calledby): data = dict() # self.data['info'] isn't used anywhere, but can be helpful in debugging. data['info'] = {'profile': profilename, 'hat': hat, 'calledby': calledby} for rule in ruletypes: data[rule] = ruletypes[rule]['ruleset']() data['alias'] = dict() data['abi'] = [] data['include'] = dict() data['localinclude'] = dict() data['lvar'] = dict() data['repo'] = dict() data['filename'] = '' data['name'] = '' data['attachment'] = '' data['flags'] = '' data['external'] = False data['header_comment'] = '' # currently only set by change_profile_flags() data['initial_comment'] = '' data['profile_keyword'] = False # currently only set by change_profile_flags() data['profile'] = False # profile or hat? data['allow'] = dict() data['deny'] = dict() data['allow']['link'] = hasher() data['deny']['link'] = hasher() # mount, pivot_root, unix have a .get() fallback to list() - initialize them nevertheless data['allow']['mount'] = list() data['deny']['mount'] = list() data['allow']['pivot_root'] = list() data['deny']['pivot_root'] = list() data['allow']['unix'] = list() data['deny']['unix'] = list() self.data = data def __getitem__(self, key): if key in self.data: return self.data[key] else: raise AppArmorBug('attempt to read unknown key %s' % key) def __setitem__(self, key, value): # TODO: Most of the keys (containing *Ruleset, dict(), list() or hasher()) should be read-only. # Their content needs to be changed, but the container shouldn't # Note: serialize_profile_from_old_profile.write_prior_segments() and write_prior_segments() expect the container to be writeable! # TODO: check if value has the expected type if key in self.data: self.data[key] = value else: raise AppArmorBug('attempt to set unknown key %s' % key) def get(self, key, fallback=None): if key in self.data: return self.data.get(key, fallback) else: raise AppArmorBug('attempt to read unknown key %s' % key) def split_flags(flags): '''split the flags given as string into a sorted, de-duplicated list''' if flags is None: flags = '' # Flags may be whitespace and/or comma separated flags_list = flags.replace(',', ' ').split() # sort and remove duplicates return sorted(set(flags_list)) def add_or_remove_flag(flags, flag_to_change, set_flag): '''add (if set_flag == True) or remove the given flag_to_change to flags''' if type_is_str(flags) or flags is None: flags = split_flags(flags) if set_flag: if flag_to_change not in flags: flags.append(flag_to_change) else: if flag_to_change in flags: flags.remove(flag_to_change) return sorted(flags) def write_abi(ref, depth): pre = ' ' * depth data = [] if ref.get('abi'): for line in ref.get('abi'): data.append('%s%s' % (pre, line)) data.append('') return data apparmor-2.13.3/utils/apparmor/logparser.py0000644000175000017500000004412613502024172016545 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2015-2018 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import ctypes import re import sys import time import LibAppArmor from apparmor.common import AppArmorException, AppArmorBug, open_file_read, DebugLogger from apparmor.aamode import validate_log_mode, log_str_to_mode, hide_log_mode, AA_MAY_EXEC # setup module translations from apparmor.translations import init_translation _ = init_translation() class ReadLog: RE_audit_time_id = '(msg=)?audit\([\d\.\:]+\):\s+' # 'audit(1282626827.320:411): ' RE_kernel_time = '\[[\d\.\s]+\]' # '[ 1612.746129]' RE_type_num = '1[45][0-9][0-9]' # 1400..1599 RE_aa_or_op = '(apparmor=|operation=)' RE_log_parts = [ 'kernel:\s+(' + RE_kernel_time + '\s+)?(audit:\s+)?type=' + RE_type_num + '\s+' + RE_audit_time_id + RE_aa_or_op, # v2_6 syslog 'kernel:\s+(' + RE_kernel_time + '\s+)?' + RE_audit_time_id + 'type=' + RE_type_num + '\s+' + RE_aa_or_op, 'type=(AVC|APPARMOR[_A-Z]*|' + RE_type_num + ')\s+' + RE_audit_time_id + '(type=' + RE_type_num + '\s+)?' + RE_aa_or_op, # v2_6 audit and dmesg 'type=USER_AVC\s+' + RE_audit_time_id + '.*apparmor=', # dbus 'type=UNKNOWN\[' + RE_type_num + '\]\s+' + RE_audit_time_id + RE_aa_or_op, 'dbus\[[0-9]+\]:\s+apparmor=', # dbus ] # used to pre-filter log lines so that we hand over only relevant lines to LibAppArmor parsing RE_LOG_ALL = re.compile('(' + '|'.join(RE_log_parts) + ')') def __init__(self, pid, filename, active_profiles, profile_dir): self.filename = filename self.profile_dir = profile_dir self.pid = pid self.active_profiles = active_profiles self.log = [] self.debug_logger = DebugLogger('ReadLog') self.LOG = None self.logmark = '' self.seenmark = None self.next_log_entry = None def prefetch_next_log_entry(self): if self.next_log_entry: sys.stderr.out('A log entry already present: %s' % self.next_log_entry) self.next_log_entry = self.LOG.readline() while not self.RE_LOG_ALL.search(self.next_log_entry) and not (self.logmark and self.logmark in self.next_log_entry): self.next_log_entry = self.LOG.readline() if not self.next_log_entry: break def get_next_log_entry(self): # If no next log entry fetch it if not self.next_log_entry: self.prefetch_next_log_entry() log_entry = self.next_log_entry self.next_log_entry = None return log_entry def peek_at_next_log_entry(self): # Take a peek at the next log entry if not self.next_log_entry: self.prefetch_next_log_entry() return self.next_log_entry def throw_away_next_log_entry(self): self.next_log_entry = None def parse_log_record(self, record): self.debug_logger.debug('parse_log_record: %s' % record) record_event = self.parse_event(record) return record_event def parse_event(self, msg): """Parse the event from log into key value pairs""" msg = msg.strip() self.debug_logger.info('parse_event: %s' % msg) #print(repr(msg)) if sys.version_info < (3, 0): # parse_record fails with u'foo' style strings hence typecasting to string msg = str(msg) event = LibAppArmor.parse_record(msg) ev = dict() ev['resource'] = event.info ev['active_hat'] = event.active_hat ev['aamode'] = event.event ev['time'] = event.epoch ev['operation'] = event.operation ev['profile'] = event.profile ev['name'] = event.name ev['name2'] = event.name2 ev['attr'] = event.attribute ev['parent'] = event.parent ev['pid'] = event.pid ev['task'] = event.task ev['info'] = event.info ev['error_code'] = event.error_code ev['denied_mask'] = event.denied_mask ev['request_mask'] = event.requested_mask ev['magic_token'] = event.magic_token ev['family'] = event.net_family ev['protocol'] = event.net_protocol ev['sock_type'] = event.net_sock_type if event.ouid != ctypes.c_ulong(-1).value: # ULONG_MAX ev['fsuid'] = event.fsuid ev['ouid'] = event.ouid if ev['operation'] and ev['operation'] == 'signal': ev['signal'] = event.signal ev['peer'] = event.peer elif ev['operation'] and ev['operation'] == 'ptrace': ev['peer'] = event.peer elif ev['operation'] and ev['operation'].startswith('dbus_'): ev['peer_profile'] = event.peer_profile ev['bus'] = event.dbus_bus ev['path'] = event.dbus_path ev['interface'] = event.dbus_interface ev['member'] = event.dbus_member LibAppArmor.free_record(event) if not ev['time']: ev['time'] = int(time.time()) # Remove None keys #for key in ev.keys(): # if not ev[key] or not re.search('[\w]+', ev[key]): # ev.pop(key) if ev['aamode']: # Convert aamode values to their counter-parts mode_convertor = {0: 'UNKNOWN', 1: 'ERROR', 2: 'AUDIT', 3: 'PERMITTING', 4: 'REJECTING', 5: 'HINT', 6: 'STATUS' } try: ev['aamode'] = mode_convertor[ev['aamode']] except KeyError: ev['aamode'] = None # "translate" disconnected paths to errors, which means the event will be ignored. # XXX Ideally we should propose to add the attach_disconnected flag to the profile if ev['error_code'] == 13 and ev['info'] == 'Failed name lookup - disconnected path': ev['aamode'] = 'ERROR' if ev['aamode']: #debug_logger.debug(ev) return ev else: return None def add_to_tree(self, loc_pid, parent, type, event): self.debug_logger.info('add_to_tree: pid [%s] type [%s] event [%s]' % (loc_pid, type, event)) if not self.pid.get(loc_pid, False): profile, hat = event[:2] if parent and self.pid.get(parent, False): if not hat: hat = 'null-complain-profile' arrayref = [] self.pid[parent].append(arrayref) self.pid[loc_pid] = arrayref for ia in ['fork', loc_pid, profile, hat]: arrayref.append(ia) # self.pid[parent].append(array_ref) # self.pid[loc_pid] = array_ref else: arrayref = [] self.log.append(arrayref) self.pid[loc_pid] = arrayref # self.log.append(array_ref) # self.pid[loc_pid] = array_ref self.pid[loc_pid].append([type, loc_pid] + event) #print("\n\npid",self.pid) #print("log",self.log) def add_event_to_tree(self, e): e = self.parse_event_for_tree(e) if e is not None: (pid, parent, mode, details) = e self.add_to_tree(pid, parent, mode, details) def parse_event_for_tree(self, e): aamode = e.get('aamode', 'UNKNOWN') if aamode == 'UNKNOWN': raise AppArmorBug('aamode is UNKNOWN - %s' % e['type']) # should never happen if aamode in ['AUDIT', 'STATUS', 'ERROR']: return None if 'profile_set' in e['operation']: return None # Skip if AUDIT event was issued due to a change_hat in unconfined mode if not e.get('profile', False): return None # Convert new null profiles to old single level null profile if '//null-' in e['profile']: e['profile'] = 'null-complain-profile' profile = e['profile'] hat = None if '//' in e['profile']: profile, hat = e['profile'].split('//')[:2] # Filter out change_hat events that aren't from learning if e['operation'] == 'change_hat': if aamode != 'HINT' and aamode != 'PERMITTING': return None if e['error_code'] == 1 and e['info'] == 'unconfined can not change_hat': return None profile = e['name2'] #hat = None if '//' in e['name2']: profile, hat = e['name2'].split('//')[:2] if not hat: hat = profile # prog is no longer passed around consistently prog = 'HINT' if profile != 'null-complain-profile' and not self.profile_exists(profile): return None if e['operation'] == 'exec': # convert rmask and dmask to mode arrays e['denied_mask'], e['name2'] = log_str_to_mode(e['profile'], e['denied_mask'], e['name2']) e['request_mask'], e['name2'] = log_str_to_mode(e['profile'], e['request_mask'], e['name2']) if e.get('info', False) and e['info'] == 'mandatory profile missing': return(e['pid'], e['parent'], 'exec', [profile, hat, aamode, 'PERMITTING', e['denied_mask'], e['name'], e['name2']]) elif (e.get('name2', False) and '//null-' in e['name2']) or e.get('name', False): return(e['pid'], e['parent'], 'exec', [profile, hat, prog, aamode, e['denied_mask'], e['name'], '']) else: self.debug_logger.debug('parse_event_for_tree: dropped exec event in %s' % e['profile']) elif self.op_type(e) == 'file': # Map c (create) and d (delete) to w (logging is more detailed than the profile language) rmask = e['request_mask'] rmask = rmask.replace('c', 'w') rmask = rmask.replace('d', 'w') if not validate_log_mode(hide_log_mode(rmask)): raise AppArmorException(_('Log contains unknown mode %s') % rmask) dmask = e['denied_mask'] dmask = dmask.replace('c', 'w') dmask = dmask.replace('d', 'w') if not validate_log_mode(hide_log_mode(dmask)): raise AppArmorException(_('Log contains unknown mode %s') % dmask) if e.get('ouid') is not None and e['fsuid'] == e['ouid']: # mark as "owner" event if '::' not in rmask: rmask = '%s::' % rmask if '::' not in dmask: dmask = '%s::' % dmask # convert rmask and dmask to mode arrays e['denied_mask'], e['name2'] = log_str_to_mode(e['profile'], dmask, e['name2']) e['request_mask'], e['name2'] = log_str_to_mode(e['profile'], rmask, e['name2']) # check if this is an exec event is_domain_change = False if e['operation'] == 'inode_permission' and (e['denied_mask'] & AA_MAY_EXEC) and aamode == 'PERMITTING': following = self.peek_at_next_log_entry() if following: entry = self.parse_log_record(following) if entry and entry.get('info', False) == 'set profile': is_domain_change = True self.throw_away_next_log_entry() if is_domain_change: return(e['pid'], e['parent'], 'exec', [profile, hat, prog, aamode, e['denied_mask'], e['name'], e['name2']]) else: return(e['pid'], e['parent'], 'path', [profile, hat, prog, aamode, e['denied_mask'], e['name'], '']) elif e['operation'] == 'capable': return(e['pid'], e['parent'], 'capability', [profile, hat, prog, aamode, e['name'], '']) elif e['operation'] == 'clone': parent, child = e['pid'], e['task'] if not parent: parent = 'null-complain-profile' if not hat: hat = 'null-complain-profile' arrayref = [] if self.pid.get(parent, False): self.pid[parent].append(arrayref) else: self.log.append(arrayref) self.pid[child].append(arrayref) for ia in ['fork', child, profile, hat]: arrayref.append(ia) # if self.pid.get(parent, False): # self.pid[parent] += [arrayref] # else: # self.log += [arrayref] # self.pid[child] = arrayref elif self.op_type(e) == 'net': return(e['pid'], e['parent'], 'netdomain', [profile, hat, prog, aamode, e['family'], e['sock_type'], e['protocol']]) elif e['operation'] == 'change_hat': return(e['pid'], e['parent'], 'unknown_hat', [profile, hat, aamode, hat]) elif e['operation'] == 'ptrace': if not e['peer']: self.debug_logger.debug('ignored garbage ptrace event with empty peer') return None if not e['denied_mask']: self.debug_logger.debug('ignored garbage ptrace event with empty denied_mask') return None return(e['pid'], e['parent'], 'ptrace', [profile, hat, prog, aamode, e['denied_mask'], e['peer']]) elif e['operation'] == 'signal': return(e['pid'], e['parent'], 'signal', [profile, hat, prog, aamode, e['denied_mask'], e['signal'], e['peer']]) elif e['operation'].startswith('dbus_'): return(e['pid'], e['parent'], 'dbus', [profile, hat, prog, aamode, e['denied_mask'], e['bus'], e['path'], e['name'], e['interface'], e['member'], e['peer_profile']]) else: self.debug_logger.debug('UNHANDLED: %s' % e) def read_log(self, logmark): self.logmark = logmark seenmark = True if self.logmark: seenmark = False #last = None #event_type = None try: #print(self.filename) self.LOG = open_file_read(self.filename) except IOError: raise AppArmorException('Can not read AppArmor logfile: ' + self.filename) #LOG = open_file_read(log_open) line = True while line: line = self.get_next_log_entry() if not line: break line = line.strip() self.debug_logger.debug('read_log: %s' % line) if self.logmark in line: seenmark = True self.debug_logger.debug('read_log: seenmark = %s' % seenmark) if not seenmark: continue event = self.parse_log_record(line) #print(event) if event: try: self.add_event_to_tree(event) except AppArmorException as e: ex_msg = ('%(msg)s\n\nThis error was caused by the log line:\n%(logline)s' % {'msg': e.value, 'logline': line}) # when py3 only: Drop the original AppArmorException by passing None as the parent exception raise AppArmorBug(ex_msg) # py3-only: from None self.LOG.close() self.logmark = '' return self.log # operation types that can be network or file operations # (used by op_type() which checks some event details to decide) OP_TYPE_FILE_OR_NET = { # Note: op_type() also uses some startswith() checks which are not listed here! 'create', 'post_create', 'bind', 'connect', 'listen', 'accept', 'sendmsg', 'recvmsg', 'getsockname', 'getpeername', 'getsockopt', 'setsockopt', 'socket_create', 'sock_shutdown', 'open', 'truncate', 'mkdir', 'mknod', 'chmod', 'chown', 'rename_src', 'rename_dest', 'unlink', 'rmdir', 'symlink_create', 'link', 'sysctl', 'getattr', 'setattr', 'xattr', } def op_type(self, event): """Returns the operation type if known, unkown otherwise""" if ( event['operation'].startswith('file_') or event['operation'].startswith('inode_') or event['operation'] in self.OP_TYPE_FILE_OR_NET ): # file or network event? if event['family'] and event['protocol'] and event['sock_type']: # 'unix' events also use keywords like 'connect', but protocol is 0 and should therefore be filtered out return 'net' elif event['denied_mask']: return 'file' else: raise AppArmorException('unknown file or network event type') else: return 'unknown' def profile_exists(self, program): """Returns True if profile exists, False otherwise""" # Check cache of profiles if self.active_profiles.filename_from_profile_name(program): return True return False def get_profile_filename(self, profile): """Returns the full profile name""" if profile.startswith('/'): # Remove leading / profile = profile[1:] else: profile = "profile_" + profile profile = profile.replace('/', '.') full_profilename = self.profile_dir + '/' + profile return full_profilename apparmor-2.13.3/utils/apparmor/ui.py0000644000175000017500000004160613502024172015164 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2017 Christian Boltz # Copyright (C) 2017 SUSE Linux # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import json import sys import re import readline import os import tempfile import subprocess from apparmor.common import readkey, AppArmorException, DebugLogger # setup module translations from apparmor.translations import init_translation _ = init_translation() # Set up UI logger for separate messages from UI module debug_logger = DebugLogger('UI') # If Python3, wrap input in raw_input so make check passes if not 'raw_input' in dir(__builtins__): raw_input = input ARROWS = {'A': 'UP', 'B': 'DOWN', 'C': 'RIGHT', 'D': 'LEFT'} UI_mode = 'text' def write_json(jsonout): print(json.dumps(jsonout, sort_keys=False, separators=(',', ': '))) sys.stdout.flush() def set_json_mode(): global UI_mode UI_mode = 'json' jsonout = {'dialog': 'apparmor-json-version', 'data': '2.12'} write_json(jsonout) # reads the response on command line for json and verifies the response # for the dialog type def json_response(dialog_type): string = raw_input('\n') rh = json.loads(string.strip()) if rh["dialog"] != dialog_type: raise AppArmorException('Expected response %s got %s.' % (dialog_type, string)) return rh def getkey(): key = readkey() if key == '\x1B': key = readkey() if key == '[': key = readkey() if(ARROWS.get(key, False)): key = ARROWS[key] return key.strip() def UI_Info(text): debug_logger.info(text) if UI_mode == 'json': jsonout = {'dialog': 'info', 'data': text} write_json(jsonout) else: # text mode sys.stdout.write(text + '\n') def UI_Important(text): debug_logger.debug(text) if UI_mode == 'json': jsonout = {'dialog': 'important', 'data': text} write_json(jsonout) else: # text mode sys.stdout.write('\n' + text + '\n') def get_translated_hotkey(translated, cmsg=''): msg = 'PromptUser: ' + _('Invalid hotkey for') # Originally (\S) was used but with translations it would not work :( if re.search('\((\S+)\)', translated): return re.search('\((\S+)\)', translated).groups()[0] else: if cmsg: raise AppArmorException(cmsg) else: raise AppArmorException('%s %s' % (msg, translated)) def UI_YesNo(text, default): debug_logger.debug('UI_YesNo: %s: %s %s' % (UI_mode, text, default)) default = default.lower() yes = CMDS['CMD_YES'] no = CMDS['CMD_NO'] yeskey = get_translated_hotkey(yes).lower() nokey = get_translated_hotkey(no).lower() ans = 'XXXINVALIDXXX' while ans not in ['y', 'n']: if UI_mode == 'json': jsonout = {'dialog': 'yesno', 'text': text, 'default': default} write_json(jsonout) hm = json_response('yesno') ans = hm['response_key'] else: # text mode sys.stdout.write('\n' + text + '\n') if default == 'y': sys.stdout.write('\n[%s] / %s\n' % (yes, no)) else: sys.stdout.write('\n%s / [%s]\n' % (yes, no)) ans = getkey() if ans: # Get back to english from localised answer ans = ans.lower() if ans == yeskey: ans = 'y' elif ans == nokey: ans = 'n' elif ans == 'left': default = 'y' elif ans == 'right': default = 'n' else: ans = 'XXXINVALIDXXX' continue # If user presses any other button ask again else: ans = default return ans def UI_YesNoCancel(text, default): debug_logger.debug('UI_YesNoCancel: %s: %s %s' % (UI_mode, text, default)) default = default.lower() yes = CMDS['CMD_YES'] no = CMDS['CMD_NO'] cancel = CMDS['CMD_CANCEL'] yeskey = get_translated_hotkey(yes).lower() nokey = get_translated_hotkey(no).lower() cancelkey = get_translated_hotkey(cancel).lower() ans = 'XXXINVALIDXXX' while ans not in ['c', 'n', 'y']: if UI_mode == 'json': jsonout = {'dialog': 'yesnocancel', 'text': text, 'default': default} write_json(jsonout) hm = json_response('yesnocancel') ans = hm['response_key'] else: # text mode sys.stdout.write('\n' + text + '\n') if default == 'y': sys.stdout.write('\n[%s] / %s / %s\n' % (yes, no, cancel)) elif default == 'n': sys.stdout.write('\n%s / [%s] / %s\n' % (yes, no, cancel)) else: sys.stdout.write('\n%s / %s / [%s]\n' % (yes, no, cancel)) ans = getkey() if ans: # Get back to english from localised answer ans = ans.lower() if ans == yeskey: ans = 'y' elif ans == nokey: ans = 'n' elif ans == cancelkey: ans = 'c' elif ans == 'left': if default == 'n': default = 'y' elif default == 'c': default = 'n' elif ans == 'right': if default == 'y': default = 'n' elif default == 'n': default = 'c' else: ans = default return ans def UI_GetString(text, default): debug_logger.debug('UI_GetString: %s: %s %s' % (UI_mode, text, default)) string = default if UI_mode == 'json': jsonout = {'dialog': 'getstring', 'text': text, 'default': default} write_json(jsonout) string = json_response('getstring')["response"] else: # text mode readline.set_startup_hook(lambda: readline.insert_text(default)) try: string = raw_input('\n' + text) except EOFError: string = '' finally: readline.set_startup_hook() return string.strip() def UI_GetFile(file): debug_logger.debug('UI_GetFile: %s' % UI_mode) filename = None if UI_mode == 'json': jsonout = {'dialog': 'getfile', 'text': file['description']} write_json(jsonout) filename = json_response('getfile')["response"] else: # text mode sys.stdout.write(file['description'] + '\n') filename = sys.stdin.read() return filename def UI_BusyStart(message): debug_logger.debug('UI_BusyStart: %s' % UI_mode) UI_Info(message) def UI_BusyStop(): debug_logger.debug('UI_BusyStop: %s' % UI_mode) def diff(oldprofile, newprofile): difftemp = tempfile.NamedTemporaryFile('w') subprocess.call('diff -u -p %s %s > %s' % (oldprofile, newprofile, difftemp.name), shell=True) return difftemp def write_profile_to_tempfile(profile): temp = tempfile.NamedTemporaryFile('w') temp.write(profile) temp.flush() return temp def generate_diff(oldprofile, newprofile): oldtemp = write_profile_to_tempfile(oldprofile) newtemp = write_profile_to_tempfile(newprofile) difftemp = diff(oldtemp.name, newtemp.name) oldtemp.close() newtemp.close() return difftemp def generate_diff_with_comments(oldprofile, newprofile): if not os.path.exists(oldprofile): raise AppArmorException(_("Can't find existing profile %s to compare changes.") % oldprofile) newtemp = write_profile_to_tempfile(newprofile) difftemp = diff(oldprofile, newtemp.name) newtemp.close() return difftemp def UI_Changes(oldprofile, newprofile, comments=False): if comments == False: difftemp = generate_diff(oldprofile, newprofile) header = 'View Changes' else: difftemp = generate_diff_with_comments(oldprofile, newprofile) header = 'View Changes with comments' if UI_mode == 'json': jsonout = {'dialog': 'changes', 'header':header, 'filename': difftemp.name} write_json(jsonout) json_response('changes')["response"] # wait for response to delay deletion of difftemp (and ignore response content) else: subprocess.call('less %s' % difftemp.name, shell=True) difftemp.close() CMDS = {'CMD_ALLOW': _('(A)llow'), 'CMD_OTHER': _('(M)ore'), 'CMD_AUDIT_NEW': _('Audi(t)'), 'CMD_AUDIT_OFF': _('Audi(t) off'), 'CMD_AUDIT_FULL': _('Audit (A)ll'), #'CMD_OTHER': '(O)pts', 'CMD_USER_ON': _('(O)wner permissions on'), 'CMD_USER_OFF': _('(O)wner permissions off'), 'CMD_DENY': _('(D)eny'), 'CMD_ABORT': _('Abo(r)t'), 'CMD_FINISHED': _('(F)inish'), 'CMD_ix': _('(I)nherit'), 'CMD_px': _('(P)rofile'), 'CMD_px_safe': _('(P)rofile Clean Exec'), 'CMD_cx': _('(C)hild'), 'CMD_cx_safe': _('(C)hild Clean Exec'), 'CMD_nx': _('(N)amed'), 'CMD_nx_safe': _('(N)amed Clean Exec'), 'CMD_ux': _('(U)nconfined'), 'CMD_ux_safe': _('(U)nconfined Clean Exec'), 'CMD_pix': _('(P)rofile Inherit'), 'CMD_pix_safe': _('(P)rofile Inherit Clean Exec'), 'CMD_cix': _('(C)hild Inherit'), 'CMD_cix_safe': _('(C)hild Inherit Clean Exec'), 'CMD_nix': _('(N)amed Inherit'), 'CMD_nix_safe': _('(N)amed Inherit Clean Exec'), 'CMD_EXEC_IX_ON': _('(X) ix On'), 'CMD_EXEC_IX_OFF': _('(X) ix Off'), 'CMD_SAVE': _('(S)ave Changes'), 'CMD_NEW': _('(N)ew'), 'CMD_GLOB': _('(G)lob'), 'CMD_GLOBEXT': _('Glob with (E)xtension'), 'CMD_ADDHAT': _('(A)dd Requested Hat'), 'CMD_ADDSUBPROFILE': _('(A)dd Requested Subprofile'), 'CMD_USEDEFAULT': _('(U)se Default Hat'), 'CMD_SCAN': _('(S)can system log for AppArmor events'), 'CMD_HELP': _('(H)elp'), 'CMD_VIEW_PROFILE': _('(V)iew Profile'), 'CMD_USE_PROFILE': _('(U)se Profile'), 'CMD_CREATE_PROFILE': _('(C)reate New Profile'), 'CMD_UPDATE_PROFILE': _('(U)pdate Profile'), 'CMD_IGNORE_UPDATE': _('(I)gnore Update'), 'CMD_SAVE_CHANGES': _('(S)ave Changes'), 'CMD_SAVE_SELECTED': _('Save Selec(t)ed Profile'), 'CMD_UPLOAD_CHANGES': _('(U)pload Changes'), 'CMD_VIEW_CHANGES': _('(V)iew Changes'), 'CMD_VIEW_CHANGES_CLEAN': _('View Changes b/w (C)lean profiles'), 'CMD_VIEW': _('(V)iew'), 'CMD_ENABLE_REPO': _('(E)nable Repository'), 'CMD_DISABLE_REPO': _('(D)isable Repository'), 'CMD_ASK_NEVER': _('(N)ever Ask Again'), 'CMD_ASK_LATER': _('Ask Me (L)ater'), 'CMD_YES': _('(Y)es'), 'CMD_NO': _('(N)o'), 'CMD_CANCEL': _('(C)ancel'), 'CMD_ALL_NET': _('Allow All (N)etwork'), 'CMD_NET_FAMILY': _('Allow Network Fa(m)ily'), 'CMD_OVERWRITE': _('(O)verwrite Profile'), 'CMD_KEEP': _('(K)eep Profile'), 'CMD_IGNORE_ENTRY': _('(I)gnore') } class PromptQuestion(object): title = None headers = None explanation = None functions = None options = None default = None selected = None helptext = None def __init__(self): self.headers = list() self.functions = list() self.selected = 0 def promptUser(self, params=''): cmd = None arg = None cmd, arg = self.Text_PromptUser() if cmd == 'CMD_ABORT': confirm_and_abort() cmd = 'XXXINVALIDXXX' return (cmd, arg) def Text_PromptUser(self): title = self.title explanation = self.explanation headers = self.headers functions = self.functions default = self.default options = self.options selected = self.selected helptext = self.helptext if helptext: functions.append('CMD_HELP') menu_items = list() keys = dict() for cmd in functions: if not CMDS.get(cmd, False): raise AppArmorException(_('PromptUser: Unknown command %s') % cmd) menutext = CMDS[cmd] key = get_translated_hotkey(menutext).lower() # Duplicate hotkey if keys.get(key, False): raise AppArmorException(_('PromptUser: Duplicate hotkey for %(command)s: %(menutext)s ') % { 'command': cmd, 'menutext': menutext }) keys[key] = cmd if default and default == cmd: menutext = '[%s]' % menutext menu_items.append(menutext) default_key = 0 if default and CMDS[default]: defaulttext = CMDS[default] defmsg = _('PromptUser: Invalid hotkey in default item') default_key = get_translated_hotkey(defaulttext, defmsg).lower() if not keys.get(default_key, False): raise AppArmorException(_('PromptUser: Invalid default %s') % default) widest = 0 header_copy = headers[:] while header_copy: header = header_copy.pop(0) header_copy.pop(0) if len(header) > widest: widest = len(header) widest += 1 formatstr = '%-' + str(widest) + 's %s\n' function_regexp = '^(' function_regexp += '|'.join(keys.keys()) if options: function_regexp += '|\d' function_regexp += ')$' ans = 'XXXINVALIDXXX' hdict = dict() jsonprompt = { 'dialog': 'promptuser', 'title': title, 'headers': hdict, 'explanation': explanation, 'options': options, 'menu_items': menu_items, 'default_key': default_key, } while not re.search(function_regexp, ans, flags=re.IGNORECASE): prompt = '\n' if title: prompt += '= %s =\n\n' % title if headers: header_copy = headers[:] while header_copy: header = header_copy.pop(0) value = header_copy.pop(0) hdict[header] = value prompt += formatstr % (header + ':', value) prompt += '\n' if explanation: prompt += explanation + '\n\n' if options: for index, option in enumerate(options): if selected == index: format_option = ' [%s - %s]' else: format_option = ' %s - %s ' prompt += format_option % (index + 1, option) prompt += '\n' prompt += ' / '.join(menu_items) if UI_mode == 'json': write_json(jsonprompt) hm = json_response('promptuser') ans = hm["response_key"] selected = hm["selected"] else: # text mode sys.stdout.write(prompt + '\n') ans = getkey().lower() if ans: if ans == 'up': if options and selected > 0: selected -= 1 ans = 'XXXINVALIDXXX' elif ans == 'down': if options and selected < len(options) - 1: selected += 1 ans = 'XXXINVALIDXXX' # elif keys.get(ans, False) == 'CMD_HELP': # sys.stdout.write('\n%s\n' %helptext) # ans = 'XXXINVALIDXXX' elif is_number(ans) == 10: # If they hit return choose default option ans = default_key elif options and re.search('^\d$', ans): ans = int(ans) if ans > 0 and ans <= len(options): selected = ans - 1 ans = 'XXXINVALIDXXX' if keys.get(ans, False) == 'CMD_HELP' and UI_mode != 'json': sys.stdout.write('\n%s\n' % helptext) ans = 'again' if keys.get(ans, False): ans = keys[ans] return ans, selected def confirm_and_abort(): ans = UI_YesNo(_('Are you sure you want to abandon this set of profile changes and exit?'), 'n') if ans == 'y': UI_Info(_('Abandoning all changes.')) sys.exit(0) def is_number(number): try: return int(number) except: return False apparmor-2.13.3/utils/apparmor/config.py0000644000175000017500000003151513502024172016012 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- from __future__ import with_statement import os import shlex import shutil import stat import sys import tempfile if sys.version_info < (3, 0): import ConfigParser as configparser # Class to provide the object[section][option] behavior in Python2 class configparser_py2(configparser.ConfigParser): def __getitem__(self, section): section_val = self.items(section) section_options = dict() for option, value in section_val: section_options[option] = value return section_options else: import configparser from apparmor.common import AppArmorException, open_file_read # , warn, msg, # CFG = None # REPO_CFG = None # SHELL_FILES = ['easyprof.conf', 'notify.conf', 'parser.conf', 'subdomain.conf'] class Config(object): def __init__(self, conf_type, conf_dir='/etc/apparmor'): self.CONF_DIR = conf_dir # The type of config file that'll be read and/or written if conf_type == 'shell' or conf_type == 'ini': self.conf_type = conf_type self.input_file = None else: raise AppArmorException("Unknown configuration file type") def new_config(self): if self.conf_type == 'shell': config = {'': dict()} elif self.conf_type == 'ini': config = configparser.ConfigParser() return config def read_config(self, filename): """Reads the file and returns a config[section][attribute]=property object""" # LP: Bug #692406 # Explicitly disabled repository filepath = self.CONF_DIR + '/' + filename self.input_file = filepath if filename == "repository.conf": config = dict() config['repository'] = {'enabled': 'no'} elif self.conf_type == 'shell': config = self.read_shell(filepath) elif self.conf_type == 'ini': if sys.version_info > (3, 0): config = configparser.ConfigParser() else: config = configparser_py2() # Set the option form to string -prevents forced conversion to lowercase config.optionxform = str if sys.version_info > (3, 0): config.read(filepath) else: try: config.read(filepath) except configparser.ParsingError: tmp_filepath = py2_parser(filepath) config.read(tmp_filepath.name) ##config.__get__() return config def write_config(self, filename, config): """Writes the given config to the specified file""" filepath = self.CONF_DIR + '/' + filename permission_600 = stat.S_IRUSR | stat.S_IWUSR # Owner read and write try: # Open a temporary file in the CONF_DIR to write the config file config_file = tempfile.NamedTemporaryFile('w', prefix='aa_temp', delete=False, dir=self.CONF_DIR) if os.path.exists(self.input_file): # Copy permissions from an existing file to temporary file shutil.copymode(self.input_file, config_file.name) else: # If no existing permission set the file permissions as 0600 os.chmod(config_file.name, permission_600) if self.conf_type == 'shell': self.write_shell(filepath, config_file, config) elif self.conf_type == 'ini': self.write_configparser(filepath, config_file, config) config_file.close() except IOError: raise AppArmorException("Unable to write to %s" % filename) else: # Replace the target config file with the temporary file os.rename(config_file.name, filepath) def find_first_file(self, file_list): """Returns name of first matching file None otherwise""" filename = None if file_list: for f in file_list.split(): if os.path.isfile(f): filename = f break return filename def find_first_dir(self, dir_list): """Returns name of first matching directory None otherwise""" dirname = None if dir_list: for direc in dir_list.split(): if os.path.isdir(direc): dirname = direc break return dirname def read_shell(self, filepath): """Reads the shell type conf files and returns config[''][option]=value""" config = {'': dict()} with open_file_read(filepath) as conf_file: for line in conf_file: result = shlex.split(line, True) # If not a comment of empty line if result: # option="value" or option=value type if '=' in result[0]: option, value = result[0].split('=') # option type else: option = result[0] value = None config[''][option] = value return config def write_shell(self, filepath, f_out, config): """Writes the config object in shell file format""" # All the options in the file options = [key for key in config[''].keys()] # If a previous file exists modify it keeping the comments if os.path.exists(self.input_file): with open_file_read(self.input_file) as f_in: for line in f_in: result = shlex.split(line, True) # If line is not empty or comment if result: # If option=value or option="value" type if '=' in result[0]: option, value = result[0].split('=') if '#' in line: comment = value.split('#', 1)[1] comment = '#' + comment else: comment = '' # If option exists in the new config file if option in options: # If value is different if value != config[''][option]: value_new = config[''][option] if value_new is not None: # Update value if '"' in line: value_new = '"' + value_new + '"' line = option + '=' + value_new + comment + '\n' else: # If option changed to option type from option=value type line = option + comment + '\n' f_out.write(line) # Remove from remaining options list options.remove(option) else: # If option type option = result[0] value = None # If option exists in the new config file if option in options: # If its no longer option type if config[''][option] is not None: value = config[''][option] line = option + '=' + value + '\n' f_out.write(line) # Remove from remaining options list options.remove(option) else: # If its empty or comment copy as it is f_out.write(line) # If any new options are present if options: for option in options: value = config[''][option] # option type entry if value is None: line = option + '\n' # option=value type entry else: line = option + '=' + value + '\n' f_out.write(line) def write_configparser(self, filepath, f_out, config): """Writes/updates the given file with given config object""" # All the sections in the file sections = config.sections() write = True section = None options = [] # If a previous file exists modify it keeping the comments if os.path.exists(self.input_file): with open_file_read(self.input_file) as f_in: for line in f_in: # If its a section if line.lstrip().startswith('['): # If any options from preceding section remain write them if options: for option in options: line_new = ' ' + option + ' = ' + config[section][option] + '\n' f_out.write(line_new) options = [] if section in sections: # Remove the written section from the list sections.remove(section) section = line.strip()[1:-1] if section in sections: # enable write for all entries in that section write = True options = config.options(section) # write the section f_out.write(line) else: # disable writing until next valid section write = False # If write enabled elif write: value = shlex.split(line, True) # If the line is empty or a comment if not value: f_out.write(line) else: option, value = line.split('=', 1) try: # split any inline comments value, comment = value.split('#', 1) comment = '#' + comment except ValueError: comment = '' if option.strip() in options: if config[section][option.strip()] != value.strip(): value = value.replace(value, config[section][option.strip()]) line = option + '=' + value + comment f_out.write(line) options.remove(option.strip()) # If any options remain from the preceding section if options: for option in options: line = ' ' + option + ' = ' + config[section][option] + '\n' f_out.write(line) options = [] # If any new sections are present if section in sections: sections.remove(section) for section in sections: f_out.write('\n[%s]\n' % section) options = config.options(section) for option in options: line = ' ' + option + ' = ' + config[section][option] + '\n' f_out.write(line) def py2_parser(filename): """Returns the de-dented ini file from the new format ini""" tmp = tempfile.NamedTemporaryFile('rw') f_out = open(tmp.name, 'w') if os.path.exists(filename): with open_file_read(filename) as f_in: for line in f_in: # The ini format allows for multi-line entries, with the subsequent # entries being indented deeper hence simple lstrip() is not appropriate if line[:2] == ' ': line = line[2:] elif line[0] == '\t': line = line[1:] f_out.write(line) f_out.flush() return tmp apparmor-2.13.3/utils/apparmor/easyprof.py0000644000175000017500000012634513502024172016403 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2011-2015 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ from __future__ import with_statement import codecs import copy import glob import json import optparse import os import re import shutil import subprocess import sys import tempfile # # TODO: move this out to the common library # #from apparmor import AppArmorException class AppArmorException(Exception): '''This class represents AppArmor exceptions''' def __init__(self, value): self.value = value def __str__(self): return repr(self.value) # # End common # DEBUGGING = False # # TODO: move this out to a utilities library # def error(out, exit_code=1, do_exit=True): '''Print error message and exit''' try: sys.stderr.write("ERROR: %s\n" % (out)) except IOError: pass if do_exit: sys.exit(exit_code) def warn(out): '''Print warning message''' try: sys.stderr.write("WARN: %s\n" % (out)) except IOError: pass def msg(out, output=sys.stdout): '''Print message''' try: sys.stdout.write("%s\n" % (out)) except IOError: pass def cmd(command): '''Try to execute the given command.''' debug(command) try: sp = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except OSError as ex: return [127, str(ex)] out = sp.communicate()[0] return [sp.returncode, out] def cmd_pipe(command1, command2): '''Try to pipe command1 into command2.''' try: sp1 = subprocess.Popen(command1, stdout=subprocess.PIPE) sp2 = subprocess.Popen(command2, stdin=sp1.stdout) except OSError as ex: return [127, str(ex)] out = sp2.communicate()[0] return [sp2.returncode, out] def debug(out): '''Print debug message''' if DEBUGGING: try: sys.stderr.write("DEBUG: %s\n" % (out)) except IOError: pass def valid_binary_path(path): '''Validate name''' try: a_path = os.path.abspath(path) except Exception: debug("Could not find absolute path for binary") return False if path != a_path: debug("Binary should use a normalized absolute path") return False if not os.path.exists(a_path): return True r_path = os.path.realpath(path) if r_path != a_path: debug("Binary should not be a symlink") return False return True def valid_variable(v): '''Validate variable name''' debug("Checking '%s'" % v) try: (key, value) = v.split('=') except Exception: return False if not re.search(r'^@\{[a-zA-Z0-9_]+\}$', key): return False if '/' in value: rel_ok = False if not value.startswith('/'): rel_ok = True if not valid_path(value, relative_ok=rel_ok): return False if '"' in value: return False # If we made it here, we are safe return True def valid_path(path, relative_ok=False): '''Valid path''' m = "Invalid path: %s" % (path) if not relative_ok and not path.startswith('/'): debug("%s (relative)" % (m)) return False if '"' in path: # We double quote elsewhere debug("%s (quote)" % (m)) return False if '../' in path: debug("%s (../ path escape)" % (m)) return False try: p = os.path.normpath(path) except Exception: debug("%s (could not normalize)" % (m)) return False if p != path: debug("%s (normalized path != path (%s != %s))" % (m, p, path)) return False # If we made it here, we are safe return True def _is_safe(s): '''Known safe regex''' if re.search(r'^[a-zA-Z_0-9\-\.]+$', s): return True return False def valid_policy_vendor(s): '''Verify the policy vendor''' return _is_safe(s) def valid_policy_version(v): '''Verify the policy version''' try: float(v) except ValueError: return False if float(v) < 0: return False return True def valid_template_name(s, strict=False): '''Verify the template name''' if not strict and s.startswith('/'): if not valid_path(s): return False return True return _is_safe(s) def valid_abstraction_name(s): '''Verify the template name''' return _is_safe(s) def valid_profile_name(s): '''Verify the profile name''' # profile name specifies path if s.startswith('/'): if not valid_path(s): return False return True # profile name does not specify path # alpha-numeric and Debian version, plus '_' if re.search(r'^[a-zA-Z0-9][a-zA-Z0-9_\+\-\.:~]+$', s): return True return False def valid_policy_group_name(s): '''Verify policy group name''' return _is_safe(s) def get_directory_contents(path): '''Find contents of the given directory''' if not valid_path(path): return None files = [] for f in glob.glob(path + "/*"): files.append(f) files.sort() return files def open_file_read(path): '''Open specified file read-only''' try: orig = codecs.open(path, 'r', "UTF-8") except Exception: raise return orig def verify_policy(policy, exe, base=None, include=None): '''Verify policy compiles''' if not exe: warn("Could not find apparmor_parser. Skipping verify") return True fn = "" # if policy starts with '/' and is one line, assume it is a path if len(policy.splitlines()) == 1 and valid_path(policy): fn = policy else: f, fn = tempfile.mkstemp(prefix='aa-easyprof') if not isinstance(policy, bytes): policy = policy.encode('utf-8') os.write(f, policy) os.close(f) command = [exe, '-QTK'] if base: command.extend(['-b', base]) if include: command.extend(['-I', include]) command.append(fn) rc, out = cmd(command) os.unlink(fn) if rc == 0: return True return False # # End utility functions # class AppArmorEasyProfile: '''Easy profile class''' def __init__(self, binary, opt): verify_options(opt) opt.ensure_value("conffile", "/etc/apparmor/easyprof.conf") self.conffile = os.path.abspath(opt.conffile) debug("Examining confile=%s" % (self.conffile)) self.dirs = dict() if os.path.isfile(self.conffile): self._get_defaults() self.parser_path = '/sbin/apparmor_parser' if opt.parser_path: self.parser_path = opt.parser_path elif not os.path.exists(self.parser_path): rc, self.parser_path = cmd(['which', 'apparmor_parser']) if rc != 0: self.parser_path = None self.parser_base = "/etc/apparmor.d" if opt.parser_base: self.parser_base = opt.parser_base self.parser_include = None if opt.parser_include: self.parser_include = opt.parser_include if opt.templates_dir and os.path.isdir(opt.templates_dir): self.dirs['templates'] = os.path.abspath(opt.templates_dir) elif not opt.templates_dir and \ opt.template and \ os.path.isfile(opt.template) and \ valid_path(opt.template): # If we specified the template and it is an absolute path, just set # the templates directory to the parent of the template so we don't # have to require --template-dir with absolute paths. self.dirs['templates'] = os.path.abspath(os.path.dirname(opt.template)) if opt.include_templates_dir and \ os.path.isdir(opt.include_templates_dir): self.dirs['templates_include'] = os.path.abspath(opt.include_templates_dir) if opt.policy_groups_dir and os.path.isdir(opt.policy_groups_dir): self.dirs['policygroups'] = os.path.abspath(opt.policy_groups_dir) if opt.include_policy_groups_dir and \ os.path.isdir(opt.include_policy_groups_dir): self.dirs['policygroups_include'] = os.path.abspath(opt.include_policy_groups_dir) self.policy_version = None self.policy_vendor = None if (opt.policy_version and not opt.policy_vendor) or \ (opt.policy_vendor and not opt.policy_version): raise AppArmorException("Must specify both policy version and vendor") # If specified --policy-version and --policy-vendor, use # templates_dir/policy_vendor/policy_version if opt.policy_version and opt.policy_vendor: self.policy_vendor = opt.policy_vendor self.policy_version = str(opt.policy_version) for i in ['templates', 'policygroups']: d = os.path.join(self.dirs[i], \ self.policy_vendor, \ self.policy_version) if not os.path.isdir(d): raise AppArmorException( "Could not find %s directory '%s'" % (i, d)) self.dirs[i] = d if not 'templates' in self.dirs: raise AppArmorException("Could not find templates directory") if not 'policygroups' in self.dirs: raise AppArmorException("Could not find policygroups directory") self.binary = binary if binary: if not valid_binary_path(binary): raise AppArmorException("Invalid path for binary: '%s'" % binary) if opt.manifest: self.set_template(opt.template, allow_abs_path=False) else: self.set_template(opt.template) self.set_policygroup(opt.policy_groups) if opt.name: self.set_name(opt.name) elif self.binary != None: self.set_name(self.binary) self.templates = [] for f in get_directory_contents(self.dirs['templates']): if os.path.isfile(f): self.templates.append(f) if 'templates_include' in self.dirs: for f in get_directory_contents(self.dirs['templates_include']): if os.path.isfile(f) and f not in self.templates: self.templates.append(f) self.policy_groups = [] for f in get_directory_contents(self.dirs['policygroups']): if os.path.isfile(f): self.policy_groups.append(f) if 'policygroups_include' in self.dirs: for f in get_directory_contents(self.dirs['policygroups_include']): if os.path.isfile(f) and f not in self.policy_groups: self.policy_groups.append(f) def _get_defaults(self): '''Read in defaults from configuration''' if not os.path.exists(self.conffile): raise AppArmorException("Could not find '%s'" % self.conffile) # Read in the configuration f = open_file_read(self.conffile) pat = re.compile(r'^\w+=".*"?') for line in f: if not pat.search(line): continue if line.startswith("POLICYGROUPS_DIR="): d = re.split(r'=', line.strip())[1].strip('["\']') self.dirs['policygroups'] = d elif line.startswith("TEMPLATES_DIR="): d = re.split(r'=', line.strip())[1].strip('["\']') self.dirs['templates'] = d f.close() keys = self.dirs.keys() if 'templates' not in keys: raise AppArmorException("Could not find TEMPLATES_DIR in '%s'" % self.conffile) if 'policygroups' not in keys: raise AppArmorException("Could not find POLICYGROUPS_DIR in '%s'" % self.conffile) for k in self.dirs.keys(): if not os.path.isdir(self.dirs[k]): raise AppArmorException("Could not find '%s'" % self.dirs[k]) def set_name(self, name): '''Set name of policy''' self.name = name def get_template(self): '''Get contents of current template''' return open(self.template).read() def set_template(self, template, allow_abs_path=True): '''Set current template''' if "../" in template: raise AppArmorException('template "%s" contains "../" escape path' % (template)) elif template.startswith('/') and not allow_abs_path: raise AppArmorException("Cannot use an absolute path template '%s'" % template) # If have an abs path, just use it if template.startswith('/'): if not os.path.exists(template): raise AppArmorException('%s does not exist' % (template)) self.template = template return # Find the template since we don't have an abs path sys_t = os.path.join(self.dirs['templates'], template) inc_t = None if 'templates_include' in self.dirs: inc_t = os.path.join(self.dirs['templates_include'], template) if os.path.exists(sys_t): self.template = sys_t elif inc_t is not None and os.path.exists(inc_t): self.template = inc_t else: raise AppArmorException('%s does not exist' % (template)) def get_templates(self): '''Get list of all available templates by filename''' return self.templates def get_policygroup(self, policygroup): '''Get contents of specific policygroup''' p = policygroup if not p.startswith('/'): sys_p = os.path.join(self.dirs['policygroups'], p) inc_p = None if 'policygroups_include' in self.dirs: inc_p = os.path.join(self.dirs['policygroups_include'], p) if os.path.exists(sys_p): p = sys_p elif inc_p is not None and os.path.exists(inc_p): p = inc_p if self.policy_groups == None or not p in self.policy_groups: raise AppArmorException("Policy group '%s' does not exist" % p) return open(p).read() def set_policygroup(self, policygroups): '''Set policygroups''' self.policy_groups = [] if policygroups != None: for p in policygroups.split(','): # If have abs path, just use it if p.startswith('/'): if not os.path.exists(p): raise AppArmorException('%s does not exist' % (p)) self.policy_groups.append(p) continue # Find the policy group since we don't have and abs path sys_p = os.path.join(self.dirs['policygroups'], p) inc_p = None if 'policygroups_include' in self.dirs: inc_p = os.path.join(self.dirs['policygroups_include'], p) if os.path.exists(sys_p): self.policy_groups.append(sys_p) elif inc_p is not None and os.path.exists(inc_p): self.policy_groups.append(inc_p) else: raise AppArmorException('%s does not exist' % (p)) def get_policy_groups(self): '''Get list of all policy groups by filename''' return self.policy_groups def gen_abstraction_rule(self, abstraction): '''Generate an abstraction rule''' base = os.path.join(self.parser_base, "abstractions", abstraction) if not os.path.exists(base): if not self.parser_include: raise AppArmorException("%s does not exist" % base) include = os.path.join(self.parser_include, "abstractions", abstraction) if not os.path.exists(include): raise AppArmorException("Neither %s nor %s exist" % (base, include)) return "#include " % abstraction def gen_variable_declaration(self, dec): '''Generate a variable declaration''' if not valid_variable(dec): raise AppArmorException("Invalid variable declaration '%s'" % dec) # Make sure we always quote k, v = dec.split('=') return '%s="%s"' % (k, v) def gen_path_rule(self, path, access): rule = [] if not path.startswith('/') and not path.startswith('@'): raise AppArmorException("'%s' should not be relative path" % path) owner = "" if path.startswith('/home/') or path.startswith("@{HOME"): owner = "owner " if path.endswith('/'): rule.append("%s %s," % (path, access)) rule.append("%s%s** %s," % (owner, path, access)) elif path.endswith('/**') or path.endswith('/*'): rule.append("%s %s," % (os.path.dirname(path), access)) rule.append("%s%s %s," % (owner, path, access)) else: rule.append("%s%s %s," % (owner, path, access)) return rule def gen_policy(self, name, binary=None, profile_name=None, template_var=[], abstractions=None, policy_groups=None, read_path=[], write_path=[], author=None, comment=None, copyright=None, no_verify=False): def find_prefix(t, s): '''Calculate whitespace prefix based on occurrence of s in t''' pat = re.compile(r'^ *%s' % s) p = "" for line in t.splitlines(): if pat.match(line): p = " " * (len(line) - len(line.lstrip())) break return p policy = self.get_template() if '###ENDUSAGE###' in policy: found = False tmp = "" for line in policy.splitlines(): if not found: if line.startswith('###ENDUSAGE###'): found = True continue tmp += line + "\n" policy = tmp attachment = "" if binary: if not valid_binary_path(binary): raise AppArmorException("Invalid path for binary: '%s'" % \ binary) if profile_name: attachment = 'profile "%s" "%s"' % (profile_name, binary) else: attachment = '"%s"' % binary elif profile_name: attachment = 'profile "%s"' % profile_name else: raise AppArmorException("Must specify binary and/or profile name") policy = re.sub(r'###PROFILEATTACH###', attachment, policy) policy = re.sub(r'###NAME###', name, policy) # Fill-in various comment fields if comment != None: policy = re.sub(r'###COMMENT###', "Comment: %s" % comment, policy) if author != None: policy = re.sub(r'###AUTHOR###', "Author: %s" % author, policy) if copyright != None: policy = re.sub(r'###COPYRIGHT###', "Copyright: %s" % copyright, policy) # Fill-in rules and variables with proper indenting search = '###ABSTRACTIONS###' prefix = find_prefix(policy, search) s = "%s# No abstractions specified" % prefix if abstractions != None: s = "%s# Specified abstractions" % (prefix) t = abstractions.split(',') t.sort() for i in t: s += "\n%s%s" % (prefix, self.gen_abstraction_rule(i)) policy = re.sub(r' *%s' % search, s, policy) search = '###POLICYGROUPS###' prefix = find_prefix(policy, search) s = "%s# No policy groups specified" % prefix if policy_groups != None: s = "%s# Rules specified via policy groups" % (prefix) t = policy_groups.split(',') t.sort() for i in t: for line in self.get_policygroup(i).splitlines(): s += "\n%s%s" % (prefix, line) if i != policy_groups.split(',')[-1]: s += "\n" policy = re.sub(r' *%s' % search, s, policy) search = '###VAR###' prefix = find_prefix(policy, search) s = "%s# No template variables specified" % prefix if len(template_var) > 0: s = "%s# Specified profile variables" % (prefix) template_var.sort() for i in template_var: s += "\n%s%s" % (prefix, self.gen_variable_declaration(i)) policy = re.sub(r' *%s' % search, s, policy) search = '###READS###' prefix = find_prefix(policy, search) s = "%s# No read paths specified" % prefix if len(read_path) > 0: s = "%s# Specified read permissions" % (prefix) read_path.sort() for i in read_path: for r in self.gen_path_rule(i, 'rk'): s += "\n%s%s" % (prefix, r) policy = re.sub(r' *%s' % search, s, policy) search = '###WRITES###' prefix = find_prefix(policy, search) s = "%s# No write paths specified" % prefix if len(write_path) > 0: s = "%s# Specified write permissions" % (prefix) write_path.sort() for i in write_path: for r in self.gen_path_rule(i, 'rwk'): s += "\n%s%s" % (prefix, r) policy = re.sub(r' *%s' % search, s, policy) if no_verify: debug("Skipping policy verification") elif not verify_policy(policy, self.parser_path, self.parser_base, self.parser_include): msg("\n" + policy) raise AppArmorException("Invalid policy") return policy def output_policy(self, params, count=0, dir=None): '''Output policy''' policy = self.gen_policy(**params) if not dir: if count: sys.stdout.write('### aa-easyprof profile #%d ###\n' % count) sys.stdout.write('%s\n' % policy) else: out_fn = "" if 'profile_name' in params: out_fn = params['profile_name'] elif 'binary' in params: out_fn = params['binary'] else: # should not ever reach this raise AppArmorException("Could not determine output filename") # Generate an absolute path, convertng any path delimiters to '.' out_fn = os.path.join(dir, re.sub(r'/', '.', out_fn.lstrip('/'))) if os.path.exists(out_fn): raise AppArmorException("'%s' already exists" % out_fn) if not os.path.exists(dir): os.mkdir(dir) if not os.path.isdir(dir): raise AppArmorException("'%s' is not a directory" % dir) f, fn = tempfile.mkstemp(prefix='aa-easyprof') if not isinstance(policy, bytes): policy = policy.encode('utf-8') os.write(f, policy) os.close(f) shutil.move(fn, out_fn) def gen_manifest(self, params): '''Take params list and output a JSON file''' d = dict() d['security'] = dict() d['security']['profiles'] = dict() pkey = "" if 'profile_name' in params: pkey = params['profile_name'] elif 'binary' in params: # when profile_name is not specified, the binary (path attachment) # also functions as the profile name pkey = params['binary'] else: raise AppArmorException("Must supply binary or profile name") d['security']['profiles'][pkey] = dict() # Add the template since it isn't part of 'params' template = os.path.basename(self.template) if template != 'default': d['security']['profiles'][pkey]['template'] = template # Add the policy_version since it isn't part of 'params' if self.policy_version: d['security']['profiles'][pkey]['policy_version'] = float(self.policy_version) if self.policy_vendor: d['security']['profiles'][pkey]['policy_vendor'] = self.policy_vendor for key in params: if key == 'profile_name' or \ (key == 'binary' and not 'profile_name' in params): continue # don't re-add the pkey elif key == 'binary' and not params[key]: continue # binary can by None when specifying --profile-name elif key == 'template_var': d['security']['profiles'][pkey]['template_variables'] = dict() for tvar in params[key]: if not self.gen_variable_declaration(tvar): raise AppArmorException("Malformed template_var '%s'" % tvar) (k, v) = tvar.split('=') k = k.lstrip('@').lstrip('{').rstrip('}') d['security']['profiles'][pkey]['template_variables'][k] = v elif key == 'abstractions' or key == 'policy_groups': d['security']['profiles'][pkey][key] = params[key].split(",") d['security']['profiles'][pkey][key].sort() else: d['security']['profiles'][pkey][key] = params[key] json_str = json.dumps(d, sort_keys=True, indent=2, separators=(',', ': ') ) return json_str def print_basefilenames(files): for i in files: sys.stdout.write("%s\n" % (os.path.basename(i))) def print_files(files): for i in files: with open(i) as f: sys.stdout.write(f.read()+"\n") def check_manifest_conflict_args(option, opt_str, value, parser): '''Check for -m/--manifest with conflicting args''' conflict_args = ['abstractions', 'read_path', 'write_path', # template always get set to 'default', can't conflict # 'template', 'policy_groups', 'policy_version', 'policy_vendor', 'name', 'profile_name', 'comment', 'copyright', 'author', 'template_var'] for conflict in conflict_args: if getattr(parser.values, conflict, False): raise optparse.OptionValueError("can't use --%s with --manifest " \ "argument" % conflict) setattr(parser.values, option.dest, value) def check_for_manifest_arg(option, opt_str, value, parser): '''Check for -m/--manifest with conflicting args''' if parser.values.manifest: raise optparse.OptionValueError("can't use --%s with --manifest " \ "argument" % opt_str.lstrip('-')) setattr(parser.values, option.dest, value) def check_for_manifest_arg_append(option, opt_str, value, parser): '''Check for -m/--manifest with conflicting args (with append)''' if parser.values.manifest: raise optparse.OptionValueError("can't use --%s with --manifest " \ "argument" % opt_str.lstrip('-')) parser.values.ensure_value(option.dest, []).append(value) def add_parser_policy_args(parser): '''Add parser arguments''' parser.add_option("--parser", dest="parser_path", help="The path to the profile parser used for verification", metavar="PATH") parser.add_option("-a", "--abstractions", action="callback", callback=check_for_manifest_arg, type=str, dest="abstractions", help="Comma-separated list of abstractions", metavar="ABSTRACTIONS") parser.add_option("-b", "--base", dest="parser_base", help="Set the base directory for resolving abstractions", metavar="DIR") parser.add_option("-I", "--Include", dest="parser_include", help="Add a directory to the search path when resolving abstractions", metavar="DIR") parser.add_option("--read-path", action="callback", callback=check_for_manifest_arg_append, type=str, dest="read_path", help="Path allowing owner reads", metavar="PATH") parser.add_option("--write-path", action="callback", callback=check_for_manifest_arg_append, type=str, dest="write_path", help="Path allowing owner writes", metavar="PATH") parser.add_option("-t", "--template", dest="template", help="Use non-default policy template", metavar="TEMPLATE", default='default') parser.add_option("--templates-dir", dest="templates_dir", help="Use non-default templates directory", metavar="DIR") parser.add_option("--include-templates-dir", dest="include_templates_dir", help="Also search DIR for templates", metavar="DIR") parser.add_option("-p", "--policy-groups", action="callback", callback=check_for_manifest_arg, type=str, help="Comma-separated list of policy groups", metavar="POLICYGROUPS") parser.add_option("--policy-groups-dir", dest="policy_groups_dir", help="Use non-default policy-groups directory", metavar="DIR") parser.add_option("--include-policy-groups-dir", dest="include_policy_groups_dir", help="Also search DIR for policy groups", metavar="DIR") parser.add_option("--policy-version", action="callback", callback=check_for_manifest_arg, type=str, dest="policy_version", help="Specify version for templates and policy groups", metavar="VERSION") parser.add_option("--policy-vendor", action="callback", callback=check_for_manifest_arg, type=str, dest="policy_vendor", help="Specify vendor for templates and policy groups", metavar="VENDOR") parser.add_option("--profile-name", action="callback", callback=check_for_manifest_arg, type=str, dest="profile_name", help="AppArmor profile name", metavar="PROFILENAME") def parse_args(args=None, parser=None): '''Parse arguments''' global DEBUGGING if parser == None: parser = optparse.OptionParser() parser.add_option("-c", "--config-file", dest="conffile", help="Use alternate configuration file", metavar="FILE") parser.add_option("-d", "--debug", help="Show debugging output", action='store_true', default=False) parser.add_option("--no-verify", help="Don't verify policy using 'apparmor_parser -p'", action='store_true', default=False) parser.add_option("--list-templates", help="List available templates", action='store_true', default=False) parser.add_option("--show-template", help="Show specified template", action='store_true', default=False) parser.add_option("--list-policy-groups", help="List available policy groups", action='store_true', default=False) parser.add_option("--show-policy-group", help="Show specified policy groups", action='store_true', default=False) parser.add_option("-n", "--name", action="callback", callback=check_for_manifest_arg, type=str, dest="name", help="Name of policy (not AppArmor profile name)", metavar="COMMENT") parser.add_option("--comment", action="callback", callback=check_for_manifest_arg, type=str, dest="comment", help="Comment for policy", metavar="COMMENT") parser.add_option("--author", action="callback", callback=check_for_manifest_arg, type=str, dest="author", help="Author of policy", metavar="COMMENT") parser.add_option("--copyright", action="callback", callback=check_for_manifest_arg, type=str, dest="copyright", help="Copyright for policy", metavar="COMMENT") parser.add_option("--template-var", action="callback", callback=check_for_manifest_arg_append, type=str, dest="template_var", help="Declare AppArmor variable", metavar="@{VARIABLE}=VALUE") parser.add_option("--output-format", action="store", dest="output_format", help="Specify output format as text (default) or json", metavar="FORMAT", default="text") parser.add_option("--output-directory", action="store", dest="output_directory", help="Output policy to this directory", metavar="DIR") # This option conflicts with any of the value arguments, e.g. name, # author, template-var, etc. parser.add_option("-m", "--manifest", action="callback", callback=check_manifest_conflict_args, type=str, dest="manifest", help="JSON manifest file", metavar="FILE") parser.add_option("--verify-manifest", action="store_true", default=False, dest="verify_manifest", help="Verify JSON manifest file") # add policy args now add_parser_policy_args(parser) (my_opt, my_args) = parser.parse_args(args) if my_opt.debug: DEBUGGING = True return (my_opt, my_args) def gen_policy_params(binary, opt): '''Generate parameters for gen_policy''' params = dict(binary=binary) if not binary and not opt.profile_name: raise AppArmorException("Must specify binary and/or profile name") if opt.profile_name: params['profile_name'] = opt.profile_name if opt.name: params['name'] = opt.name else: if opt.profile_name: params['name'] = opt.profile_name elif binary: params['name'] = os.path.basename(binary) if opt.template_var: # What about specified multiple times? params['template_var'] = opt.template_var if opt.abstractions: params['abstractions'] = opt.abstractions if opt.policy_groups: params['policy_groups'] = opt.policy_groups if opt.read_path: params['read_path'] = opt.read_path if opt.write_path: params['write_path'] = opt.write_path if opt.comment: params['comment'] = opt.comment if opt.author: params['author'] = opt.author if opt.copyright: params['copyright'] = opt.copyright if opt.policy_version and opt.output_format == "json": params['policy_version'] = opt.policy_version if opt.policy_vendor and opt.output_format == "json": params['policy_vendor'] = opt.policy_vendor return params def parse_manifest(manifest, opt_orig): '''Take a JSON manifest as a string and updates options, returning an updated binary. Note that a JSON file may contain multiple profiles.''' try: m = json.loads(manifest) except ValueError: raise AppArmorException("Could not parse manifest") if 'security' in m: top_table = m['security'] else: top_table = m if 'profiles' not in top_table: raise AppArmorException("Could not parse manifest (could not find 'profiles')") table = top_table['profiles'] # generally mirrors what is settable in gen_policy_params() valid_keys = ['abstractions', 'author', 'binary', 'comment', 'copyright', 'name', 'policy_groups', 'policy_version', 'policy_vendor', 'profile_name', 'read_path', 'template', 'template_variables', 'write_path', ] profiles = [] for profile_name in table: if not isinstance(table[profile_name], dict): raise AppArmorException("Wrong JSON structure") opt = copy.deepcopy(opt_orig) # The JSON structure is: # { # "security": { # : { # "binary": ... # ... # but because binary can be the profile name, we need to handle # 'profile_name' and 'binary' special. If a profile_name starts with # '/', then it is considered the binary. Otherwise, set the # profile_name and set the binary if it is in the JSON. binary = None if profile_name.startswith('/'): if 'binary' in table[profile_name]: raise AppArmorException("Profile name should not specify path with binary") binary = profile_name else: setattr(opt, 'profile_name', profile_name) if 'binary' in table[profile_name]: binary = table[profile_name]['binary'] setattr(opt, 'binary', binary) for key in table[profile_name]: if key not in valid_keys: raise AppArmorException("Invalid key '%s'" % key) if key == 'binary': continue # handled above elif key == 'abstractions' or key == 'policy_groups': setattr(opt, key, ",".join(table[profile_name][key])) elif key == "template_variables": t = table[profile_name]['template_variables'] vlist = [] for v in t.keys(): vlist.append("@{%s}=%s" % (v, t[v])) setattr(opt, 'template_var', vlist) else: if hasattr(opt, key): setattr(opt, key, table[profile_name][key]) profiles.append( (binary, opt) ) return profiles def verify_options(opt, strict=False): '''Make sure our options are valid''' if hasattr(opt, 'binary') and opt.binary and not valid_path(opt.binary): raise AppArmorException("Invalid binary '%s'" % opt.binary) if hasattr(opt, 'profile_name') and opt.profile_name != None and \ not valid_profile_name(opt.profile_name): raise AppArmorException("Invalid profile name '%s'" % opt.profile_name) if hasattr(opt, 'binary') and opt.binary and \ hasattr(opt, 'profile_name') and opt.profile_name != None and \ opt.profile_name.startswith('/'): raise AppArmorException("Profile name should not specify path with binary") if hasattr(opt, 'policy_vendor') and opt.policy_vendor and \ not valid_policy_vendor(opt.policy_vendor): raise AppArmorException("Invalid policy vendor '%s'" % \ opt.policy_vendor) if hasattr(opt, 'policy_version') and opt.policy_version and \ not valid_policy_version(opt.policy_version): raise AppArmorException("Invalid policy version '%s'" % \ opt.policy_version) if hasattr(opt, 'template') and opt.template and \ not valid_template_name(opt.template, strict): raise AppArmorException("Invalid template '%s'" % opt.template) if hasattr(opt, 'template_var') and opt.template_var: for i in opt.template_var: if not valid_variable(i): raise AppArmorException("Invalid variable '%s'" % i) if hasattr(opt, 'policy_groups') and opt.policy_groups: for i in opt.policy_groups.split(','): if not valid_policy_group_name(i): raise AppArmorException("Invalid policy group '%s'" % i) if hasattr(opt, 'abstractions') and opt.abstractions: for i in opt.abstractions.split(','): if not valid_abstraction_name(i): raise AppArmorException("Invalid abstraction '%s'" % i) if hasattr(opt, 'read_paths') and opt.read_paths: for i in opt.read_paths: if not valid_path(i): raise AppArmorException("Invalid read path '%s'" % i) if hasattr(opt, 'write_paths') and opt.write_paths: for i in opt.write_paths: if not valid_path(i): raise AppArmorException("Invalid write path '%s'" % i) def verify_manifest(params, args=None): '''Verify manifest for safe and unsafe options''' err_str = "" (opt, args) = parse_args(args) fake_easyp = AppArmorEasyProfile(None, opt) unsafe_keys = ['read_path', 'write_path'] safe_abstractions = ['base'] for k in params: debug("Examining %s=%s" % (k, params[k])) if k in unsafe_keys: err_str += "\nfound %s key" % k elif k == 'profile_name': if params['profile_name'].startswith('/') or \ '*' in params['profile_name']: err_str += "\nprofile_name '%s'" % params['profile_name'] elif k == 'abstractions': for a in params['abstractions'].split(','): if not a in safe_abstractions: err_str += "\nfound '%s' abstraction" % a elif k == "template_var": pat = re.compile(r'[*/\{\}\[\]]') for tv in params['template_var']: if not fake_easyp.gen_variable_declaration(tv): err_str += "\n%s" % tv continue tv_val = tv.split('=')[1] debug("Examining %s" % tv_val) if '..' in tv_val or pat.search(tv_val): err_str += "\n%s" % tv if err_str: warn("Manifest definition is potentially unsafe%s" % err_str) return False return True apparmor-2.13.3/utils/apparmor/aa.py0000644000175000017500000040767613502024172015145 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2014-2018 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- # No old version logs, only 2.6 + supported from __future__ import division, with_statement import os import re import shutil import subprocess import sys import time import traceback import atexit import tempfile import apparmor.config import apparmor.logparser import apparmor.severity from copy import deepcopy from apparmor.aare import AARE from apparmor.common import (AppArmorException, AppArmorBug, open_file_read, valid_path, hasher, open_file_write, DebugLogger) import apparmor.ui as aaui from apparmor.aamode import str_to_mode, split_mode from apparmor.regex import (RE_PROFILE_START, RE_PROFILE_END, RE_PROFILE_LINK, RE_ABI, RE_PROFILE_ALIAS, RE_PROFILE_BOOLEAN, RE_PROFILE_VARIABLE, RE_PROFILE_CONDITIONAL, RE_PROFILE_CONDITIONAL_VARIABLE, RE_PROFILE_CONDITIONAL_BOOLEAN, RE_PROFILE_CHANGE_HAT, RE_PROFILE_HAT_DEF, RE_PROFILE_MOUNT, RE_PROFILE_PIVOT_ROOT, RE_PROFILE_UNIX, RE_RULE_HAS_COMMA, RE_HAS_COMMENT_SPLIT, strip_quotes, parse_profile_start_line, re_match_include ) from apparmor.profile_list import ProfileList from apparmor.profile_storage import ProfileStorage, add_or_remove_flag, ruletypes, write_abi import apparmor.rules as aarules from apparmor.rule.capability import CapabilityRule from apparmor.rule.change_profile import ChangeProfileRule from apparmor.rule.dbus import DbusRule from apparmor.rule.file import FileRule from apparmor.rule.network import NetworkRule from apparmor.rule.ptrace import PtraceRule from apparmor.rule.rlimit import RlimitRule from apparmor.rule.signal import SignalRule from apparmor.rule import quote_if_needed # setup module translations from apparmor.translations import init_translation _ = init_translation() # Setup logging incase of debugging is enabled debug_logger = DebugLogger('aa') # The database for severity sev_db = None # The file to read log messages from ### Was our logfile = None CONFDIR = None conf = None cfg = None repo_cfg = None parser = None profile_dir = None extra_profile_dir = None ### end our # To keep track of previously included profile fragments include = dict() active_profiles = ProfileList() extra_profiles = ProfileList() # To store the globs entered by users so they can be provided again # format: user_globs['/foo*'] = AARE('/foo*') user_globs = {} ## Variables used under logprof transitions = hasher() aa = hasher() # Profiles originally in sd, replace by aa original_aa = hasher() extras = hasher() # Inactive profiles from extras ### end our log_pid = dict() # handed over to ReadLog, gets filled in logparser.py. The only case the previous content of this variable _might_(?) be used is aa-genprof (multiple do_logprof_pass() runs) profile_changes = dict() prelog = hasher() changed = dict() created = [] helpers = dict() # Preserve this between passes # was our ### logprof ends filelist = hasher() # File level variables and stuff in config files def on_exit(): """Shutdowns the logger and records exit if debugging enabled""" debug_logger.debug('Exiting..') debug_logger.shutdown() # Register the on_exit method with atexit atexit.register(on_exit) def check_for_LD_XXX(file): """Returns True if specified program contains references to LD_PRELOAD or LD_LIBRARY_PATH to give the Px/Ux code better suggestions""" if not os.path.isfile(file): return False size = os.stat(file).st_size # Limit to checking files under 100k for the sake of speed if size > 100000: return False with open(file, 'rb') as f_in: for line in f_in: if b'LD_PRELOAD' in line or b'LD_LIBRARY_PATH' in line: return True return False def fatal_error(message): # Get the traceback to the message tb_stack = traceback.format_list(traceback.extract_stack()) tb_stack = ''.join(tb_stack) # Add the traceback to message message = tb_stack + '\n\n' + message debug_logger.error(message) # Else tell user what happened aaui.UI_Important(message) sys.exit(1) def check_for_apparmor(filesystem='/proc/filesystems', mounts='/proc/mounts'): """Finds and returns the mountpoint for apparmor None otherwise""" support_securityfs = False aa_mountpoint = None if valid_path(filesystem): with open_file_read(filesystem) as f_in: for line in f_in: if 'securityfs' in line: support_securityfs = True break if valid_path(mounts) and support_securityfs: with open_file_read(mounts) as f_in: for line in f_in: split = line.split() if len(split) > 2 and split[2] == 'securityfs': mountpoint = split[1] + '/apparmor' # Check if apparmor is actually mounted there # XXX valid_path() only checks the syntax, but not if the directory exists! if valid_path(mountpoint) and valid_path(mountpoint + '/profiles'): aa_mountpoint = mountpoint break return aa_mountpoint def which(file): """Returns the executable fullpath for the file, None otherwise""" if sys.version_info >= (3, 3): return shutil.which(file) env_dirs = os.getenv('PATH').split(':') for env_dir in env_dirs: env_path = env_dir + '/' + file # Test if the path is executable or not if os.access(env_path, os.X_OK): return env_path return None def get_full_path(original_path): """Return the full path after resolving any symlinks""" path = original_path link_count = 0 if not path.startswith('/'): path = os.getcwd() + '/' + path while os.path.islink(path): link_count += 1 if link_count > 64: fatal_error(_("Followed too many links while resolving %s") % (original_path)) direc, file = os.path.split(path) link = os.readlink(path) # If the link an absolute path if link.startswith('/'): path = link else: # Link is relative path path = direc + '/' + link return os.path.realpath(path) def find_executable(bin_path): """Returns the full executable path for the given executable, None otherwise""" full_bin = None if os.path.exists(bin_path): full_bin = get_full_path(bin_path) else: if '/' not in bin_path: env_bin = which(bin_path) if env_bin: full_bin = get_full_path(env_bin) if full_bin and os.path.exists(full_bin): return full_bin return None def get_profile_filename_from_profile_name(profile, get_new=False): """Returns the full profile name for the given profile name""" filename = active_profiles.filename_from_profile_name(profile) if filename: return filename if get_new: return get_new_profile_filename(profile) def get_profile_filename_from_attachment(profile, get_new=False): """Returns the full profile name for the given attachment""" filename = active_profiles.filename_from_attachment(profile) if filename: return filename if get_new: return get_new_profile_filename(profile) def get_new_profile_filename(profile): '''Compose filename for a new profile''' if profile.startswith('/'): # Remove leading / profile = profile[1:] else: profile = "profile_" + profile profile = profile.replace('/', '.') full_profilename = profile_dir + '/' + profile return full_profilename def name_to_prof_filename(prof_filename): """Returns the profile""" if prof_filename.startswith(profile_dir): profile = prof_filename.split(profile_dir, 1)[1] return (prof_filename, profile) else: bin_path = find_executable(prof_filename) if bin_path: prof_filename = get_profile_filename_from_attachment(bin_path, True) if os.path.isfile(prof_filename): return (prof_filename, bin_path) return None, None def complain(path): """Sets the profile to complain mode if it exists""" prof_filename, name = name_to_prof_filename(path) if not prof_filename: fatal_error(_("Can't find %s") % path) set_complain(prof_filename, name) def enforce(path): """Sets the profile to enforce mode if it exists""" prof_filename, name = name_to_prof_filename(path) if not prof_filename: fatal_error(_("Can't find %s") % path) set_enforce(prof_filename, name) def set_complain(filename, program): """Sets the profile to complain mode""" aaui.UI_Info(_('Setting %s to complain mode.') % (filename if program is None else program)) # a force-complain symlink is more packaging-friendly, but breaks caching # create_symlink('force-complain', filename) delete_symlink('disable', filename) change_profile_flags(filename, program, 'complain', True) def set_enforce(filename, program): """Sets the profile to enforce mode""" aaui.UI_Info(_('Setting %s to enforce mode.') % (filename if program is None else program)) delete_symlink('force-complain', filename) delete_symlink('disable', filename) change_profile_flags(filename, program, 'complain', False) def delete_symlink(subdir, filename): path = filename link = re.sub('^%s' % profile_dir, '%s/%s' % (profile_dir, subdir), path) if link != path and os.path.islink(link): os.remove(link) def create_symlink(subdir, filename): path = filename bname = os.path.basename(filename) if not bname: raise AppArmorException(_('Unable to find basename for %s.') % filename) #print(filename) link = re.sub('^%s' % profile_dir, '%s/%s' % (profile_dir, subdir), path) #print(link) #link = link + '/%s'%bname #print(link) symlink_dir = os.path.dirname(link) if not os.path.exists(symlink_dir): # If the symlink directory does not exist create it os.makedirs(symlink_dir) if not os.path.exists(link): try: os.symlink(filename, link) except: raise AppArmorException(_('Could not create %(link)s symlink to %(file)s.') % { 'link': link, 'file': filename }) def head(file): """Returns the first/head line of the file""" first = '' if os.path.isfile(file): with open_file_read(file) as f_in: try: first = f_in.readline().rstrip() except UnicodeDecodeError: pass return first else: raise AppArmorException(_('Unable to read first line from %s: File Not Found') % file) def get_output(params): '''Runs the program with the given args and returns the return code and stdout (as list of lines)''' try: # Get the output of the program output = subprocess.check_output(params) ret = 0 except OSError as e: raise AppArmorException(_("Unable to fork: %(program)s\n\t%(error)s") % { 'program': params[0], 'error': str(e) }) except subprocess.CalledProcessError as e: # If exit code != 0 output = e.output ret = e.returncode output = output.decode('utf-8').split('\n') # Remove the extra empty string caused due to \n if present if output[len(output) - 1] == '': output.pop() return (ret, output) def get_reqs(file): """Returns a list of paths from ldd output""" pattern1 = re.compile('^\s*\S+ => (\/\S+)') pattern2 = re.compile('^\s*(\/\S+)') reqs = [] ldd = conf.find_first_file(cfg['settings'].get('ldd')) or '/usr/bin/ldd' if not os.path.isfile(ldd) or not os.access(ldd, os.EX_OK): raise AppArmorException('Can\'t find ldd') ret, ldd_out = get_output([ldd, file]) if ret == 0 or ret == 1: for line in ldd_out: if 'not a dynamic executable' in line: # comes with ret == 1 break if 'cannot read header' in line: break if 'statically linked' in line: break match = pattern1.search(line) if match: reqs.append(match.groups()[0]) else: match = pattern2.search(line) if match: reqs.append(match.groups()[0]) return reqs def handle_binfmt(profile, path): """Modifies the profile to add the requirements""" reqs_processed = dict() reqs = get_reqs(path) while reqs: library = reqs.pop() library = get_full_path(library) # resolve symlinks if not reqs_processed.get(library, False): if get_reqs(library): reqs += get_reqs(library) reqs_processed[library] = True library_rule = FileRule(library, 'mr', None, FileRule.ALL, owner=False, log_event=True) if not is_known_rule(profile, 'file', library_rule): globbed_library = glob_common(library) if globbed_library: # glob_common returns a list, just use the first element (typically '/lib/libfoo.so.*') library_rule = FileRule(globbed_library[0], 'mr', None, FileRule.ALL, owner=False) profile['file'].add(library_rule) def get_interpreter_and_abstraction(exec_target): '''Check if exec_target is a script. If a hashbang is found, check if we have an abstraction for it. Returns (interpreter_path, abstraction) - interpreter_path is none if exec_target is not a script or doesn't have a hashbang line - abstraction is None if no matching abstraction exists''' if not os.path.exists(exec_target): aaui.UI_Important(_('Execute target %s does not exist!') % exec_target) return None, None if not os.path.isfile(exec_target): aaui.UI_Important(_('Execute target %s is not a file!') % exec_target) return None, None hashbang = head(exec_target) if not hashbang.startswith('#!'): return None, None # get the interpreter (without parameters) interpreter = hashbang[2:].strip().split()[0] interpreter_path = get_full_path(interpreter) interpreter = re.sub('^(/usr)?/bin/', '', interpreter_path) if interpreter in ['bash', 'dash', 'sh']: abstraction = 'abstractions/bash' elif interpreter == 'perl': abstraction = 'abstractions/perl' elif re.search('^python([23]|[23]\.[0-9]+)?$', interpreter): abstraction = 'abstractions/python' elif re.search('^ruby([0-9]+(\.[0-9]+)*)?$', interpreter): abstraction = 'abstractions/ruby' else: abstraction = None return interpreter_path, abstraction def get_inactive_profile(local_profile): if extras.get(local_profile, False): return {local_profile: extras[local_profile]} return dict() def create_new_profile(localfile, is_stub=False): local_profile = hasher() local_profile[localfile] = ProfileStorage('NEW', localfile, 'create_new_profile()') local_profile[localfile]['flags'] = 'complain' local_profile[localfile]['include']['abstractions/base'] = 1 if os.path.exists(localfile) and os.path.isfile(localfile): interpreter_path, abstraction = get_interpreter_and_abstraction(localfile) if interpreter_path: local_profile[localfile]['file'].add(FileRule(localfile, 'r', None, FileRule.ALL, owner=False)) local_profile[localfile]['file'].add(FileRule(interpreter_path, None, 'ix', FileRule.ALL, owner=False)) if abstraction: local_profile[localfile]['include'][abstraction] = True handle_binfmt(local_profile[localfile], interpreter_path) else: local_profile[localfile]['file'].add(FileRule(localfile, 'mr', None, FileRule.ALL, owner=False)) handle_binfmt(local_profile[localfile], localfile) # Add required hats to the profile if they match the localfile for hatglob in cfg['required_hats'].keys(): if re.search(hatglob, localfile): for hat in sorted(cfg['required_hats'][hatglob].split()): if not local_profile.get(hat, False): local_profile[hat] = ProfileStorage('NEW', hat, 'create_new_profile() required_hats') local_profile[hat]['flags'] = 'complain' if not is_stub: created.append(localfile) changed[localfile] = True debug_logger.debug("Profile for %s:\n\t%s" % (localfile, local_profile.__str__())) return {localfile: local_profile} def delete_profile(local_prof): """Deletes the specified file from the disk and remove it from our list""" profile_file = get_profile_filename_from_profile_name(local_prof, True) if os.path.isfile(profile_file): os.remove(profile_file) if aa.get(local_prof, False): aa.pop(local_prof) #prof_unload(local_prof) def confirm_and_abort(): ans = aaui.UI_YesNo(_('Are you sure you want to abandon this set of profile changes and exit?'), 'n') if ans == 'y': aaui.UI_Info(_('Abandoning all changes.')) for prof in created: delete_profile(prof) sys.exit(0) def get_profile(prof_name): profile_data = None distro = cfg['repository']['distro'] repo_url = cfg['repository']['url'] # local_profiles = [] profile_hash = hasher() if repo_is_enabled(): aaui.UI_BusyStart(_('Connecting to repository...')) status_ok, ret = fetch_profiles_by_name(repo_url, distro, prof_name) aaui.UI_BusyStop() if status_ok: profile_hash = ret else: aaui.UI_Important(_('WARNING: Error fetching profiles from the repository')) inactive_profile = get_inactive_profile(prof_name) if inactive_profile: uname = 'Inactive local profile for %s' % prof_name inactive_profile[prof_name][prof_name]['flags'] = 'complain' orig_filename = inactive_profile[prof_name][prof_name]['filename'] # needed for CMD_VIEW_PROFILE inactive_profile[prof_name][prof_name]['filename'] = '' profile_hash[uname]['username'] = uname profile_hash[uname]['profile_type'] = 'INACTIVE_LOCAL' profile_hash[uname]['profile'] = serialize_profile(inactive_profile[prof_name], prof_name, None) profile_hash[uname]['profile_data'] = inactive_profile # no longer necessary after splitting active and extra profiles # existing_profiles.pop(prof_name) # remove profile filename from list to force storing in /etc/apparmor.d/ instead of extra_profile_dir # If no profiles in repo and no inactive profiles if not profile_hash.keys(): return None options = [] tmp_list = [] preferred_present = False preferred_user = cfg['repository'].get('preferred_user', 'NOVELL') for p in profile_hash.keys(): if profile_hash[p]['username'] == preferred_user: preferred_present = True else: tmp_list.append(profile_hash[p]['username']) if preferred_present: options.append(preferred_user) options += tmp_list q = aaui.PromptQuestion() q.headers = ['Profile', prof_name] q.functions = ['CMD_VIEW_PROFILE', 'CMD_USE_PROFILE', 'CMD_CREATE_PROFILE', 'CMD_ABORT'] q.default = "CMD_VIEW_PROFILE" q.options = options q.selected = 0 ans = '' while 'CMD_USE_PROFILE' not in ans and 'CMD_CREATE_PROFILE' not in ans: ans, arg = q.promptUser() p = profile_hash[options[arg]] q.selected = options.index(options[arg]) if ans == 'CMD_VIEW_PROFILE': pager = get_pager() subprocess.call([pager, orig_filename]) elif ans == 'CMD_USE_PROFILE': if p['profile_type'] == 'INACTIVE_LOCAL': profile_data = p['profile_data'] created.append(prof_name) else: profile_data = parse_repo_profile(prof_name, repo_url, p) return profile_data def activate_repo_profiles(url, profiles, complain): read_profiles() try: for p in profiles: pname = p[0] profile_data = parse_repo_profile(pname, url, p[1]) attach_profile_data(aa, profile_data) write_profile(pname) if complain: fname = get_profile_filename_from_profile_name(pname, True) change_profile_flags(profile_dir + fname, None, 'complain', True) aaui.UI_Info(_('Setting %s to complain mode.') % pname) except Exception as e: sys.stderr.write(_("Error activating profiles: %s") % e) def autodep(bin_name, pname=''): bin_full = None global repo_cfg if not repo_cfg and not cfg['repository'].get('url', False): repo_conf = apparmor.config.Config('shell', CONFDIR) repo_cfg = repo_conf.read_config('repository.conf') if not repo_cfg.get('repository', False) or repo_cfg['repository']['enabled'] == 'later': UI_ask_to_enable_repo() if bin_name: bin_full = find_executable(bin_name) #if not bin_full: # bin_full = bin_name #if not bin_full.startswith('/'): #return None # Return if exectuable path not found if not bin_full: return None else: bin_full = pname # for named profiles pname = bin_full read_inactive_profiles() profile_data = get_profile(pname) # Create a new profile if no existing profile if not profile_data: profile_data = create_new_profile(pname) file = get_profile_filename_from_profile_name(pname, True) profile_data[pname][pname]['filename'] = None # will be stored in /etc/apparmor.d when saving, so it shouldn't carry the extra_profile_dir filename attach_profile_data(aa, profile_data) attach_profile_data(original_aa, profile_data) if os.path.isfile(profile_dir + '/tunables/global'): if not filelist.get(file, False): filelist[file] = hasher() filelist[file]['include']['tunables/global'] = True filelist[file]['profiles'][pname] = hasher() filelist[file]['profiles'][pname][pname] = True write_profile_ui_feedback(pname) def get_profile_flags(filename, program): # To-Do # XXX If more than one profile in a file then second one is being ignored XXX # Do we return flags for both or flags = '' with open_file_read(filename) as f_in: for line in f_in: if RE_PROFILE_START.search(line): matches = parse_profile_start_line(line, filename) if (matches['attachment'] is not None): profile_glob = AARE(matches['attachment'], True) else: profile_glob = AARE(matches['profile'], True) flags = matches['flags'] if (program is not None and profile_glob.match(program)) or program is None or program == matches['profile']: return flags raise AppArmorException(_('%s contains no profile') % filename) def change_profile_flags(prof_filename, program, flag, set_flag): """Reads the old profile file and updates the flags accordingly""" # TODO: count the number of matching lines (separated by profile and hat?) and return it # so that code calling this function can make sure to only report success if there was a match # TODO: change child profile flags even if program is specified found = False if not flag or flag.strip() == '': raise AppArmorBug('New flag for %s is empty' % prof_filename) with open_file_read(prof_filename) as f_in: temp_file = tempfile.NamedTemporaryFile('w', prefix=prof_filename, suffix='~', delete=False, dir=profile_dir) shutil.copymode(prof_filename, temp_file.name) with open_file_write(temp_file.name) as f_out: for line in f_in: if RE_PROFILE_START.search(line): matches = parse_profile_start_line(line, prof_filename) space = matches['leadingspace'] or '' profile = matches['profile'] old_flags = matches['flags'] newflags = ', '.join(add_or_remove_flag(old_flags, flag, set_flag)) if (matches['attachment'] is not None): profile_glob = AARE(matches['attachment'], True) else: profile_glob = AARE(matches['profile'], False) # named profiles can come without an attachment path specified ("profile foo {...}") if (program is not None and profile_glob.match(program)) or program is None or program == matches['profile']: found = True if program is not None and program != profile: aaui.UI_Info(_('Warning: profile %s represents multiple programs') % profile) header_data = { 'attachment': matches['attachment'] or '', 'flags': newflags, 'profile_keyword': matches['profile_keyword'], 'header_comment': matches['comment'] or '', } line = write_header(header_data, len(space)/2, profile, False, True) line = '%s\n' % line[0] elif RE_PROFILE_HAT_DEF.search(line): matches = RE_PROFILE_HAT_DEF.search(line) space = matches.group('leadingspace') or '' hat_keyword = matches.group('hat_keyword') hat = matches.group('hat') old_flags = matches['flags'] newflags = ', '.join(add_or_remove_flag(old_flags, flag, set_flag)) comment = matches.group('comment') or '' if comment: comment = ' %s' % comment if newflags: line = '%s%s%s flags=(%s) {%s\n' % (space, hat_keyword, hat, newflags, comment) else: line = '%s%s%s {%s\n' % (space, hat_keyword, hat, comment) f_out.write(line) os.rename(temp_file.name, prof_filename) if not found: if program is None: raise AppArmorException("%(file)s doesn't contain a valid profile (syntax error?)" % {'file': prof_filename}) else: raise AppArmorException("%(file)s doesn't contain a valid profile for %(profile)s (syntax error?)" % {'file': prof_filename, 'profile': program}) def profile_exists(program): """Returns True if profile exists, False otherwise""" # Check cache of profiles if active_profiles.filename_from_attachment(program): return True # Check the disk for profile prof_path = get_profile_filename_from_attachment(program, True) #print(prof_path) if os.path.isfile(prof_path): # Add to cache of profile raise AppArmorBug('Reached strange condition in profile_exists(), please open a bugreport!') # active_profiles[program] = prof_path # return True return False def sync_profile(): user, passw = get_repo_user_pass() if not user or not passw: return None repo_profiles = [] changed_profiles = [] new_profiles = [] serialize_opts = dict() status_ok, ret = fetch_profiles_by_user(cfg['repository']['url'], cfg['repository']['distro'], user) if not status_ok: if not ret: ret = 'UNKNOWN ERROR' aaui.UI_Important(_('WARNING: Error synchronizing profiles with the repository:\n%s\n') % ret) else: users_repo_profiles = ret serialize_opts['NO_FLAGS'] = True for prof in sorted(aa.keys()): if is_repo_profile([aa[prof][prof]]): repo_profiles.append(prof) if prof in created: p_local = serialize_profile(aa[prof], prof, serialize_opts) if not users_repo_profiles.get(prof, False): new_profiles.append(prof) new_profiles.append(p_local) new_profiles.append('') else: p_repo = users_repo_profiles[prof]['profile'] if p_local != p_repo: changed_profiles.append(prof) changed_profiles.append(p_local) changed_profiles.append(p_repo) if repo_profiles: for prof in repo_profiles: p_local = serialize_profile(aa[prof], prof, serialize_opts) if not users_repo_profiles.get(prof, False): new_profiles.append(prof) new_profiles.append(p_local) new_profiles.append('') else: p_repo = '' if aa[prof][prof]['repo']['user'] == user: p_repo = users_repo_profiles[prof]['profile'] else: status_ok, ret = fetch_profile_by_id(cfg['repository']['url'], aa[prof][prof]['repo']['id']) if status_ok: p_repo = ret['profile'] else: if not ret: ret = 'UNKNOWN ERROR' aaui.UI_Important(_('WARNING: Error synchronizing profiles with the repository\n%s') % ret) continue if p_repo != p_local: changed_profiles.append(prof) changed_profiles.append(p_local) changed_profiles.append(p_repo) if changed_profiles: submit_changed_profiles(changed_profiles) if new_profiles: submit_created_profiles(new_profiles) def fetch_profile_by_id(url, id): #To-Do return None, None def fetch_profiles_by_name(url, distro, user): #to-Do return None, None def fetch_profiles_by_user(url, distro, user): #to-Do return None, None def submit_created_profiles(new_profiles): #url = cfg['repository']['url'] if new_profiles: title = 'Submit newly created profiles to the repository' message = 'Would you like to upload newly created profiles?' console_select_and_upload_profiles(title, message, new_profiles) def submit_changed_profiles(changed_profiles): #url = cfg['repository']['url'] if changed_profiles: title = 'Submit changed profiles to the repository' message = 'The following profiles from the repository were changed.\nWould you like to upload your changes?' console_select_and_upload_profiles(title, message, changed_profiles) def upload_profile(url, user, passw, distro, p, profile_string, changelog): # To-Do return None, None def console_select_and_upload_profiles(title, message, profiles_up): url = cfg['repository']['url'] profiles = profiles_up[:] q = aaui.PromptQuestion() q.title = title q.headers = ['Repository', url] q.explanation = message q.functions = ['CMD_UPLOAD_CHANGES', 'CMD_VIEW_CHANGES', 'CMD_ASK_LATER', 'CMD_ASK_NEVER', 'CMD_ABORT'] q.default = 'CMD_VIEW_CHANGES' q.options = [i[0] for i in profiles] q.selected = 0 ans = '' while 'CMD_UPLOAD_CHANGES' not in ans and 'CMD_ASK_NEVER' not in ans and 'CMD_ASK_LATER' not in ans: ans, arg = q.promptUser() if ans == 'CMD_VIEW_CHANGES': aaui.UI_Changes(profiles[arg][2], profiles[arg][1]) if ans == 'CMD_NEVER_ASK': set_profiles_local_only([i[0] for i in profiles]) elif ans == 'CMD_UPLOAD_CHANGES': changelog = aaui.UI_GetString(_('Changelog Entry: '), '') user, passw = get_repo_user_pass() if user and passw: for p_data in profiles: prof = p_data[0] prof_string = p_data[1] status_ok, ret = upload_profile(url, user, passw, cfg['repository']['distro'], prof, prof_string, changelog) if status_ok: newprof = ret newid = newprof['id'] set_repo_info(aa[prof][prof], url, user, newid) write_profile_ui_feedback(prof) aaui.UI_Info('Uploaded %s to repository' % prof) else: if not ret: ret = 'UNKNOWN ERROR' aaui.UI_Important(_('WARNING: An error occurred while uploading the profile %(profile)s\n%(ret)s') % { 'profile': prof, 'ret': ret }) else: aaui.UI_Important(_('Repository Error\nRegistration or Signin was unsuccessful. User login\ninformation is required to upload profiles to the repository.\nThese changes could not be sent.')) def set_profiles_local_only(profiles): for p in profiles: aa[profiles][profiles]['repo']['neversubmit'] = True write_profile_ui_feedback(profiles) def build_x_functions(default, options, exec_toggle): ret_list = [] fallback_toggle = False if exec_toggle: if 'i' in options: ret_list.append('CMD_ix') if 'p' in options: ret_list.append('CMD_pix') fallback_toggle = True if 'c' in options: ret_list.append('CMD_cix') fallback_toggle = True if 'n' in options: ret_list.append('CMD_nix') fallback_toggle = True if fallback_toggle: ret_list.append('CMD_EXEC_IX_OFF') if 'u' in options: ret_list.append('CMD_ux') else: if 'i' in options: ret_list.append('CMD_ix') if 'c' in options: ret_list.append('CMD_cx') fallback_toggle = True if 'p' in options: ret_list.append('CMD_px') fallback_toggle = True if 'n' in options: ret_list.append('CMD_nx') fallback_toggle = True if 'u' in options: ret_list.append('CMD_ux') if fallback_toggle: ret_list.append('CMD_EXEC_IX_ON') ret_list += ['CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'] return ret_list def handle_children(profile, hat, root): entries = root[:] pid = None p = None h = None prog = None aamode = None mode = None detail = None to_name = None uhat = None capability = None family = None sock_type = None protocol = None regex_nullcomplain = re.compile('^null(-complain)*-profile$') for entry in entries: if type(entry[0]) != str: handle_children(profile, hat, entry) else: typ = entry.pop(0) if typ == 'fork': # If type is fork then we (should) have pid, profile and hat pid, p, h = entry[:3] if not regex_nullcomplain.search(p) and not regex_nullcomplain.search(h): profile = p hat = h if hat: profile_changes[pid] = profile + '//' + hat else: profile_changes[pid] = profile elif typ == 'unknown_hat': # If hat is not known then we (should) have pid, profile, hat, mode and unknown hat in entry pid, p, h, aamode, uhat = entry[:5] if not regex_nullcomplain.search(p): profile = p if aa[profile].get(uhat, False): hat = uhat continue new_p = update_repo_profile(aa[profile][profile]) if new_p and UI_SelectUpdatedRepoProfile(profile, new_p) and aa[profile].get(uhat, False): hat = uhat continue default_hat = None for hatglob in cfg.options('defaulthat'): if re.search(hatglob, profile): default_hat = cfg['defaulthat'][hatglob] context = profile context = context + ' -> ^%s' % uhat ans = transitions.get(context, 'XXXINVALIDXXX') while ans not in ['CMD_ADDHAT', 'CMD_USEDEFAULT', 'CMD_DENY']: q = aaui.PromptQuestion() q.headers += [_('Profile'), profile] if default_hat: q.headers += [_('Default Hat'), default_hat] q.headers += [_('Requested Hat'), uhat] q.functions.append('CMD_ADDHAT') if default_hat: q.functions.append('CMD_USEDEFAULT') q.functions += ['CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'] q.default = 'CMD_DENY' if aamode == 'PERMITTING': q.default = 'CMD_ADDHAT' ans = q.promptUser()[0] if ans == 'CMD_FINISHED': save_profiles() return transitions[context] = ans if ans == 'CMD_ADDHAT': hat = uhat aa[profile][hat] = ProfileStorage(profile, hat, 'handle_children addhat') aa[profile][hat]['flags'] = aa[profile][profile]['flags'] changed[profile] = True elif ans == 'CMD_USEDEFAULT': hat = default_hat elif ans == 'CMD_DENY': # As unknown hat is denied no entry for it should be made continue elif typ == 'capability': # If capability then we (should) have pid, profile, hat, program, mode, capability pid, p, h, prog, aamode, capability = entry[:6] if not regex_nullcomplain.search(p) and not regex_nullcomplain.search(h): profile = p hat = h if not profile or not hat: continue prelog[aamode][profile][hat]['capability'][capability] = True elif typ == 'dbus': # If dbus then we (should) have pid, profile, hat, program, mode, access, bus, name, path, interface, member, peer_profile pid, p, h, prog, aamode, access, bus, path, name, interface, member, peer_profile = entry if not regex_nullcomplain.search(p) and not regex_nullcomplain.search(h): profile = p hat = h if not profile or not hat: continue prelog[aamode][profile][hat]['dbus'][access][bus][path][name][interface][member][peer_profile] = True elif typ == 'ptrace': # If ptrace then we (should) have pid, profile, hat, program, mode, access and peer pid, p, h, prog, aamode, access, peer = entry if not regex_nullcomplain.search(p) and not regex_nullcomplain.search(h): profile = p hat = h if not profile or not hat: continue prelog[aamode][profile][hat]['ptrace'][peer][access] = True elif typ == 'signal': # If signal then we (should) have pid, profile, hat, program, mode, access, signal and peer pid, p, h, prog, aamode, access, signal, peer = entry if not regex_nullcomplain.search(p) and not regex_nullcomplain.search(h): profile = p hat = h if not profile or not hat: continue prelog[aamode][profile][hat]['signal'][peer][access][signal] = True elif typ == 'path' or typ == 'exec': # If path or exec then we (should) have pid, profile, hat, program, mode, details and to_name pid, p, h, prog, aamode, mode, detail, to_name = entry[:8] if not mode: mode = set() if not regex_nullcomplain.search(p) and not regex_nullcomplain.search(h): profile = p hat = h if not profile or not hat or not detail: continue # Give Execute dialog if x access requested for something that's not a directory # For directories force an 'ix' Path dialog do_execute = False exec_target = detail if mode & str_to_mode('x'): if os.path.isdir(exec_target): raise AppArmorBug('exec permissions requested for directory %s. This should not happen - please open a bugreport!' % exec_target) elif typ != 'exec': raise AppArmorBug('exec permissions requested for %(exec_target)s, but mode is %(mode)s instead of exec. This should not happen - please open a bugreport!' % {'exec_target': exec_target, 'mode':mode}) else: do_execute = True domainchange = 'change' if mode and mode != str_to_mode('x'): # x is already handled in handle_children, so it must not become part of prelog path = detail if prelog[aamode][profile][hat]['path'].get(path, False): mode |= prelog[aamode][profile][hat]['path'][path] prelog[aamode][profile][hat]['path'][path] = mode if do_execute: if not aa[profile][hat]: continue # ignore log entries for non-existing profiles exec_event = FileRule(exec_target, None, FileRule.ANY_EXEC, FileRule.ALL, owner=False, log_event=True) if is_known_rule(aa[profile][hat], 'file', exec_event): continue p = update_repo_profile(aa[profile][profile]) if to_name: if UI_SelectUpdatedRepoProfile(profile, p) and is_known_rule(aa[profile][hat], 'file', exec_event): # we need an exec_event with target=to_name here continue else: if UI_SelectUpdatedRepoProfile(profile, p) and is_known_rule(aa[profile][hat], 'file', exec_event): # we need an exec_event with target=exec_target here continue context_new = profile if profile != hat: context_new = context_new + '^%s' % hat context_new = context_new + ' -> %s' % exec_target # nx is not used in profiles but in log files. # Log parsing methods will convert it to its profile form # nx is internally cx/px/cix/pix + to_name exec_mode = False file_perm = None if True: options = cfg['qualifiers'].get(exec_target, 'ipcnu') if to_name: fatal_error(_('%s has transition name but not transition mode') % entry) ### If profiled program executes itself only 'ix' option ##if exec_target == profile: ##options = 'i' # Don't allow hats to cx? options.replace('c', '') # Add deny to options options += 'd' # Define the default option default = None if 'p' in options and os.path.exists(get_profile_filename_from_attachment(exec_target, True)): default = 'CMD_px' sys.stdout.write(_('Target profile exists: %s\n') % get_profile_filename_from_attachment(exec_target, True)) elif 'i' in options: default = 'CMD_ix' elif 'c' in options: default = 'CMD_cx' elif 'n' in options: default = 'CMD_nx' else: default = 'DENY' # parent_uses_ld_xxx = check_for_LD_XXX(profile) sev_db.unload_variables() sev_db.load_variables(get_profile_filename_from_profile_name(profile, True)) severity = sev_db.rank_path(exec_target, 'x') # Prompt portion starts q = aaui.PromptQuestion() q.headers += [_('Profile'), combine_name(profile, hat)] if prog and prog != 'HINT': q.headers += [_('Program'), prog] # to_name should not exist here since, transitioning is already handeled q.headers += [_('Execute'), exec_target] q.headers += [_('Severity'), severity] # prompt = '\n%s\n' % context_new # XXX exec_toggle = False q.functions += build_x_functions(default, options, exec_toggle) # ask user about the exec mode to use ans = '' while ans not in ['CMD_ix', 'CMD_px', 'CMD_cx', 'CMD_nx', 'CMD_pix', 'CMD_cix', 'CMD_nix', 'CMD_ux', 'CMD_DENY']: # add '(I)gnore'? (hotkey conflict with '(i)x'!) ans = q.promptUser()[0] if ans.startswith('CMD_EXEC_IX_'): exec_toggle = not exec_toggle q.functions = build_x_functions(default, options, exec_toggle) ans = '' continue if ans == 'CMD_FINISHED': save_profiles() return if ans == 'CMD_nx' or ans == 'CMD_nix': arg = exec_target ynans = 'n' if profile == hat: ynans = aaui.UI_YesNo(_('Are you specifying a transition to a local profile?'), 'n') if ynans == 'y': if ans == 'CMD_nx': ans = 'CMD_cx' else: ans = 'CMD_cix' else: if ans == 'CMD_nx': ans = 'CMD_px' else: ans = 'CMD_pix' to_name = aaui.UI_GetString(_('Enter profile name to transition to: '), arg) if ans == 'CMD_ix': exec_mode = 'ix' elif ans in ['CMD_px', 'CMD_cx', 'CMD_pix', 'CMD_cix']: exec_mode = ans.replace('CMD_', '') px_msg = _("Should AppArmor sanitise the environment when\nswitching profiles?\n\nSanitising environment is more secure,\nbut some applications depend on the presence\nof LD_PRELOAD or LD_LIBRARY_PATH.") if parent_uses_ld_xxx: px_msg = _("Should AppArmor sanitise the environment when\nswitching profiles?\n\nSanitising environment is more secure,\nbut this application appears to be using LD_PRELOAD\nor LD_LIBRARY_PATH and sanitising the environment\ncould cause functionality problems.") ynans = aaui.UI_YesNo(px_msg, 'y') if ynans == 'y': # Disable the unsafe mode exec_mode = exec_mode.capitalize() elif ans == 'CMD_ux': exec_mode = 'ux' ynans = aaui.UI_YesNo(_("Launching processes in an unconfined state is a very\ndangerous operation and can cause serious security holes.\n\nAre you absolutely certain you wish to remove all\nAppArmor protection when executing %s ?") % exec_target, 'n') if ynans == 'y': ynans = aaui.UI_YesNo(_("Should AppArmor sanitise the environment when\nrunning this program unconfined?\n\nNot sanitising the environment when unconfining\na program opens up significant security holes\nand should be avoided if at all possible."), 'y') if ynans == 'y': # Disable the unsafe mode exec_mode = exec_mode.capitalize() else: ans = 'INVALID' if exec_mode and 'i' in exec_mode: # For inherit we need mr file_perm = 'mr' else: if ans == 'CMD_DENY': aa[profile][hat]['file'].add(FileRule(exec_target, None, 'x', FileRule.ALL, owner=False, log_event=True, deny=True)) changed[profile] = True # Skip remaining events if they ask to deny exec if domainchange == 'change': return None if ans != 'CMD_DENY': if to_name: rule_to_name = to_name else: rule_to_name = FileRule.ALL aa[profile][hat]['file'].add(FileRule(exec_target, file_perm, exec_mode, rule_to_name, owner=False, log_event=True)) changed[profile] = True if 'i' in exec_mode: interpreter_path, abstraction = get_interpreter_and_abstraction(exec_target) if interpreter_path: aa[profile][hat]['file'].add(FileRule(exec_target, 'r', None, FileRule.ALL, owner=False)) aa[profile][hat]['file'].add(FileRule(interpreter_path, None, 'ix', FileRule.ALL, owner=False)) if abstraction: aa[profile][hat]['include'][abstraction] = True handle_binfmt(aa[profile][hat], interpreter_path) # Update tracking info based on kind of change if ans == 'CMD_ix': if hat: profile_changes[pid] = '%s//%s' % (profile, hat) else: profile_changes[pid] = '%s//' % profile elif re.search('^CMD_(px|nx|pix|nix)', ans): if to_name: exec_target = to_name if aamode == 'PERMITTING': if domainchange == 'change': profile = exec_target hat = exec_target profile_changes[pid] = '%s' % profile # Check profile exists for px if not os.path.exists(get_profile_filename_from_attachment(exec_target, True)): ynans = 'y' if 'i' in exec_mode: ynans = aaui.UI_YesNo(_('A profile for %s does not exist.\nDo you want to create one?') % exec_target, 'n') if ynans == 'y': helpers[exec_target] = 'enforce' if to_name: autodep('', exec_target) else: autodep(exec_target, '') reload_base(exec_target) elif ans.startswith('CMD_cx') or ans.startswith('CMD_cix'): if to_name: exec_target = to_name if aamode == 'PERMITTING': if domainchange == 'change': profile_changes[pid] = '%s//%s' % (profile, exec_target) if not aa[profile].get(exec_target, False): ynans = 'y' if 'i' in exec_mode: ynans = aaui.UI_YesNo(_('A profile for %s does not exist.\nDo you want to create one?') % exec_target, 'n') if ynans == 'y': hat = exec_target if not aa[profile].get(hat, False): stub_profile = create_new_profile(hat, True) aa[profile][hat] = stub_profile[hat][hat] aa[profile][hat]['profile'] = True if profile != hat: aa[profile][hat]['flags'] = aa[profile][profile]['flags'] aa[profile][hat]['flags'] = 'complain' file_name = aa[profile][profile]['filename'] filelist[file_name]['profiles'][profile][hat] = True elif ans.startswith('CMD_ux'): profile_changes[pid] = 'unconfined' if domainchange == 'change': return None elif typ == 'netdomain': # If netdomain we (should) have pid, profile, hat, program, mode, network family, socket type and protocol pid, p, h, prog, aamode, family, sock_type, protocol = entry[:8] if not regex_nullcomplain.search(p) and not regex_nullcomplain.search(h): profile = p hat = h if not hat or not profile: continue if family and sock_type: prelog[aamode][profile][hat]['netdomain'][family][sock_type] = True return None ##### Repo related functions def UI_SelectUpdatedRepoProfile(profile, p): # To-Do return False def UI_repo_signup(): # To-Do return None, None def UI_ask_to_enable_repo(): # To-Do pass def UI_ask_to_upload_profiles(): # To-Do pass def parse_repo_profile(fqdbin, repo_url, profile): # To-Do pass def set_repo_info(profile_data, repo_url, username, iden): # To-Do pass def is_repo_profile(profile_data): # To-Do pass def get_repo_user_pass(): # To-Do pass def get_preferred_user(repo_url): # To-Do pass def repo_is_enabled(): # To-Do return False def update_repo_profile(profile): # To-Do return None def order_globs(globs, original_path): """Returns the globs in sorted order, more specific behind""" # To-Do # ATM its lexicographic, should be done to allow better matches later globs = sorted(globs) # make sure the original path is always the last option if original_path in globs: globs.remove(original_path) globs.append(original_path) return globs def ask_the_questions(log_dict): for aamode in sorted(log_dict.keys()): # Describe the type of changes if aamode == 'PERMITTING': aaui.UI_Info(_('Complain-mode changes:')) elif aamode == 'REJECTING': aaui.UI_Info(_('Enforce-mode changes:')) elif aamode == 'merge': pass # aa-mergeprof else: raise AppArmorBug(_('Invalid mode found: %s') % aamode) for profile in sorted(log_dict[aamode].keys()): # Update the repo profiles p = update_repo_profile(aa[profile][profile]) if p: UI_SelectUpdatedRepoProfile(profile, p) sev_db.unload_variables() sev_db.load_variables(get_profile_filename_from_profile_name(profile, True)) # Sorted list of hats with the profile name coming first hats = list(filter(lambda key: key != profile, sorted(log_dict[aamode][profile].keys()))) if log_dict[aamode][profile].get(profile, False): hats = [profile] + hats for hat in hats: if not aa[profile].get(hat, {}).get('file'): if aamode != 'merge': # Ignore log events for a non-existing profile or child profile. Such events can occour # after deleting a profile or hat manually, or when processing a foreign log. # (Checking for 'file' is a simplified way to check if it's a ProfileStorage.) debug_logger.debug("Ignoring events for non-existing profile %s" % combine_name(profile, hat)) continue ans = '' while ans not in ['CMD_ADDHAT', 'CMD_ADDSUBPROFILE', 'CMD_DENY']: q = aaui.PromptQuestion() q.headers += [_('Profile'), profile] if log_dict[aamode][profile][hat]['profile']: q.headers += [_('Requested Subprofile'), hat] q.functions.append('CMD_ADDSUBPROFILE') else: q.headers += [_('Requested Hat'), hat] q.functions.append('CMD_ADDHAT') q.functions += ['CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'] q.default = 'CMD_DENY' ans = q.promptUser()[0] if ans == 'CMD_FINISHED': return if ans == 'CMD_DENY': continue # don't ask about individual rules if the user doesn't want the additional subprofile/hat if log_dict[aamode][profile][hat]['profile']: aa[profile][hat] = ProfileStorage(profile, hat, 'mergeprof ask_the_questions() - missing subprofile') aa[profile][hat]['profile'] = True else: aa[profile][hat] = ProfileStorage(profile, hat, 'mergeprof ask_the_questions() - missing hat') aa[profile][hat]['profile'] = False #Add the includes from the other profile to the user profile done = False options = [] for inc in log_dict[aamode][profile][hat]['include'].keys(): if not inc in aa[profile][hat]['include'].keys(): if inc.startswith('/'): options.append('#include "%s"' %inc) else: options.append('#include <%s>' %inc) default_option = 1 q = aaui.PromptQuestion() q.options = options q.selected = default_option - 1 q.headers = [_('File includes'), _('Select the ones you wish to add')] q.functions = ['CMD_ALLOW', 'CMD_IGNORE_ENTRY', 'CMD_ABORT', 'CMD_FINISHED'] q.default = 'CMD_ALLOW' while not done and options: ans, selected = q.promptUser() if ans == 'CMD_IGNORE_ENTRY': done = True elif ans == 'CMD_ALLOW': selection = options[selected] inc = re_match_include(selection) deleted = apparmor.aa.delete_duplicates(aa[profile][hat], inc) aa[profile][hat]['include'][inc] = True options.pop(selected) aaui.UI_Info(_('Adding %s to the file.') % selection) if deleted: aaui.UI_Info(_('Deleted %s previous matching profile entries.') % deleted) elif ans == 'CMD_FINISHED': return # check for and ask about conflicting exec modes ask_conflict_mode(profile, hat, aa[profile][hat], log_dict[aamode][profile][hat]) for ruletype in ruletypes: for rule_obj in log_dict[aamode][profile][hat][ruletype].rules: if is_known_rule(aa[profile][hat], ruletype, rule_obj): continue default_option = 1 options = [] newincludes = match_includes(aa[profile][hat], ruletype, rule_obj) q = aaui.PromptQuestion() if newincludes: options += list(map(lambda inc: '#include <%s>' % inc, sorted(set(newincludes)))) if ruletype == 'file' and rule_obj.path: options += propose_file_rules(aa[profile][hat], rule_obj) else: options.append(rule_obj.get_clean()) done = False while not done: q.options = options q.selected = default_option - 1 q.headers = [_('Profile'), combine_name(profile, hat)] q.headers += rule_obj.logprof_header() # Load variables into sev_db? Not needed/used for capabilities and network rules. severity = rule_obj.severity(sev_db) if severity != sev_db.NOT_IMPLEMENTED: q.headers += [_('Severity'), severity] q.functions = available_buttons(rule_obj) # In complain mode: events default to allow # In enforce mode: events default to deny # XXX does this behaviour really make sense, except for "historical reasons"[tm]? q.default = 'CMD_DENY' if rule_obj.log_event == 'PERMITTING': q.default = 'CMD_ALLOW' ans, selected = q.promptUser() selection = options[selected] if ans == 'CMD_IGNORE_ENTRY': done = True break elif ans == 'CMD_FINISHED': return elif ans.startswith('CMD_AUDIT'): if ans == 'CMD_AUDIT_NEW': rule_obj.audit = True rule_obj.raw_rule = None else: rule_obj.audit = False rule_obj.raw_rule = None options = set_options_audit_mode(rule_obj, options) elif ans.startswith('CMD_USER_'): if ans == 'CMD_USER_ON': rule_obj.owner = True rule_obj.raw_rule = None else: rule_obj.owner = False rule_obj.raw_rule = None options = set_options_owner_mode(rule_obj, options) elif ans == 'CMD_ALLOW': done = True changed[profile] = True inc = re_match_include(selection) if inc: deleted = delete_duplicates(aa[profile][hat], inc) aa[profile][hat]['include'][inc] = True aaui.UI_Info(_('Adding %s to profile.') % selection) if deleted: aaui.UI_Info(_('Deleted %s previous matching profile entries.') % deleted) else: rule_obj = selection_to_rule_obj(rule_obj, selection) deleted = aa[profile][hat][ruletype].add(rule_obj, cleanup=True) aaui.UI_Info(_('Adding %s to profile.') % rule_obj.get_clean()) if deleted: aaui.UI_Info(_('Deleted %s previous matching profile entries.') % deleted) elif ans == 'CMD_DENY': if re_match_include(selection): aaui.UI_Important("Denying via an include file isn't supported by the AppArmor tools") else: done = True changed[profile] = True rule_obj = selection_to_rule_obj(rule_obj, selection) rule_obj.deny = True rule_obj.raw_rule = None # reset raw rule after manually modifying rule_obj deleted = aa[profile][hat][ruletype].add(rule_obj, cleanup=True) aaui.UI_Info(_('Adding %s to profile.') % rule_obj.get_clean()) if deleted: aaui.UI_Info(_('Deleted %s previous matching profile entries.') % deleted) elif ans == 'CMD_GLOB': if not re_match_include(selection): globbed_rule_obj = selection_to_rule_obj(rule_obj, selection) globbed_rule_obj.glob() options, default_option = add_to_options(options, globbed_rule_obj.get_raw()) elif ans == 'CMD_GLOBEXT': if not re_match_include(selection): globbed_rule_obj = selection_to_rule_obj(rule_obj, selection) globbed_rule_obj.glob_ext() options, default_option = add_to_options(options, globbed_rule_obj.get_raw()) elif ans == 'CMD_NEW': if not re_match_include(selection): edit_rule_obj = selection_to_rule_obj(rule_obj, selection) prompt, oldpath = edit_rule_obj.edit_header() newpath = aaui.UI_GetString(prompt, oldpath) if newpath: try: input_matches_path = rule_obj.validate_edit(newpath) # note that we check against the original rule_obj here, not edit_rule_obj (which might be based on a globbed path) except AppArmorException: aaui.UI_Important(_('The path you entered is invalid (not starting with / or a variable)!')) continue if not input_matches_path: ynprompt = _('The specified path does not match this log entry:\n\n Log Entry: %(path)s\n Entered Path: %(ans)s\nDo you really want to use this path?') % { 'path': oldpath, 'ans': newpath } key = aaui.UI_YesNo(ynprompt, 'n') if key == 'n': continue edit_rule_obj.store_edit(newpath) options, default_option = add_to_options(options, edit_rule_obj.get_raw()) user_globs[newpath] = AARE(newpath, True) else: done = False def selection_to_rule_obj(rule_obj, selection): rule_type = type(rule_obj) return rule_type.parse(selection) def set_options_audit_mode(rule_obj, options): '''change audit state in options (proposed rules) to audit state in rule_obj. #include options will be kept unchanged ''' return set_options_mode(rule_obj, options, 'audit') def set_options_owner_mode(rule_obj, options): '''change owner state in options (proposed rules) to owner state in rule_obj. #include options will be kept unchanged ''' return set_options_mode(rule_obj, options, 'owner') def set_options_mode(rule_obj, options, what): ''' helper function for set_options_audit_mode() and set_options_owner_mode''' new_options = [] for rule in options: if re_match_include(rule): new_options.append(rule) else: parsed_rule = selection_to_rule_obj(rule_obj, rule) if what == 'audit': parsed_rule.audit = rule_obj.audit elif what == 'owner': parsed_rule.owner = rule_obj.owner else: raise AppArmorBug('Unknown "what" value given to set_options_mode: %s' % what) parsed_rule.raw_rule = None new_options.append(parsed_rule.get_raw()) return new_options def available_buttons(rule_obj): buttons = [] if not rule_obj.deny: buttons += ['CMD_ALLOW'] buttons += ['CMD_DENY', 'CMD_IGNORE_ENTRY'] if rule_obj.can_glob: buttons += ['CMD_GLOB'] if rule_obj.can_glob_ext: buttons += ['CMD_GLOBEXT'] if rule_obj.can_edit: buttons += ['CMD_NEW'] if rule_obj.audit: buttons += ['CMD_AUDIT_OFF'] else: buttons += ['CMD_AUDIT_NEW'] if rule_obj.can_owner: if rule_obj.owner: buttons += ['CMD_USER_OFF'] else: buttons += ['CMD_USER_ON'] buttons += ['CMD_ABORT', 'CMD_FINISHED'] return buttons def add_to_options(options, newpath): if newpath not in options: options.append(newpath) default_option = options.index(newpath) + 1 return (options, default_option) def delete_duplicates(profile, incname): deleted = 0 # Allow rules covered by denied rules shouldn't be deleted # only a subset allow rules may actually be denied if include.get(incname, False): for rule_type in ruletypes: deleted += profile[rule_type].delete_duplicates(include[incname][incname][rule_type]) elif filelist.get(incname, False): for rule_type in ruletypes: deleted += profile[rule_type].delete_duplicates(filelist[incname][incname][rule_type]) return deleted def ask_conflict_mode(profile, hat, old_profile, merge_profile): '''ask user about conflicting exec rules''' for oldrule in old_profile['file'].rules: conflictingrules = merge_profile['file'].get_exec_conflict_rules(oldrule) if conflictingrules.rules: q = aaui.PromptQuestion() q.headers = [_('Path'), oldrule.path.regex] q.headers += [_('Select the appropriate mode'), ''] options = [] options.append(oldrule.get_clean()) for rule in conflictingrules.rules: options.append(rule.get_clean()) q.options = options q.functions = ['CMD_ALLOW', 'CMD_ABORT'] done = False while not done: ans, selected = q.promptUser() if ans == 'CMD_ALLOW': if selected == 0: pass # just keep the existing rule elif selected > 0: # replace existing rule with merged one old_profile['file'].delete(oldrule) old_profile['file'].add(conflictingrules.rules[selected - 1]) else: raise AppArmorException(_('Unknown selection')) for rule in conflictingrules.rules: merge_profile['file'].delete(rule) # make sure aa-mergeprof doesn't ask to add conflicting rules later done = True def get_include_path(incname): if incname.startswith('/'): return incname return profile_dir + '/' + incname def match_includes(profile, rule_type, rule_obj): newincludes = [] for incname in include.keys(): # XXX type check should go away once we init all profiles correctly if valid_include(profile, incname) and include[incname][incname].get(rule_type, False) and include[incname][incname][rule_type].is_covered(rule_obj): newincludes.append(incname) return newincludes def valid_include(profile, incname): if profile and profile['include'].get(incname, False): return False if cfg['settings']['custom_includes']: for incm in cfg['settings']['custom_includes'].split(): if incm == incname: return True if incname.startswith('abstractions/') and os.path.isfile(profile_dir + '/' + incname): return True elif incname.startswith('/') and os.path.isfile(incname): return True return False def set_logfile(filename): ''' set logfile to a) the specified filename or b) if not given, the first existing logfile from logprof.conf''' global logfile if filename: logfile = filename elif 'logfiles' in cfg['settings']: # This line can only run if the 'logfile' exists in settings, otherwise # it will yield a Python KeyError logfile = conf.find_first_file(cfg['settings']['logfiles']) or '/var/log/syslog' else: logfile = '/var/log/syslog' if not os.path.exists(logfile): if filename: raise AppArmorException(_('The logfile %s does not exist. Please check the path.') % logfile) else: raise AppArmorException('Can\'t find system log "%s". Please check permissions.' % (logfile)) elif os.path.isdir(logfile): raise AppArmorException(_('%s is a directory. Please specify a file as logfile') % logfile) def do_logprof_pass(logmark='', passno=0, log_pid=log_pid): # set up variables for this pass # transitions = hasher() global active_profiles global sev_db # aa = hasher() # profile_changes = hasher() # prelog = hasher() # changed = dict() # filelist = hasher() aaui.UI_Info(_('Reading log entries from %s.') % logfile) if not passno: aaui.UI_Info(_('Updating AppArmor profiles in %s.') % profile_dir) read_profiles() if not sev_db: sev_db = apparmor.severity.Severity(CONFDIR + '/severity.db', _('unknown')) #print(pid) #print(active_profiles) ##if not repo_cf and cfg['repostory']['url']: ## repo_cfg = read_config('repository.conf') ## if not repo_cfg['repository'].get('enabled', False) or repo_cfg['repository]['enabled'] not in ['yes', 'no']: ## UI_ask_to_enable_repo() log_reader = apparmor.logparser.ReadLog(log_pid, logfile, active_profiles, profile_dir) log = log_reader.read_log(logmark) #read_log(logmark) for root in log: handle_children('', '', root) #for root in range(len(log)): #log[root] = handle_children('', '', log[root]) #print(log) for pid in sorted(profile_changes.keys()): set_process(pid, profile_changes[pid]) log_dict = collapse_log() ask_the_questions(log_dict) finishing = False # Check for finished save_profiles() ##if not repo_cfg['repository'].get('upload', False) or repo['repository']['upload'] == 'later': ## UI_ask_to_upload_profiles() ##if repo_enabled(): ## if repo_cgf['repository']['upload'] == 'yes': ## sync_profiles() ## created = [] # If user selects 'Finish' then we want to exit logprof if finishing: return 'FINISHED' else: return 'NORMAL' def save_profiles(): # Ensure the changed profiles are actual active profiles for prof_name in changed.keys(): if not is_active_profile(prof_name): print("*** save_profiles(): removing %s" % prof_name) print('*** This should not happen. Please open a bugreport!') changed.pop(prof_name) changed_list = sorted(changed.keys()) if changed_list: q = aaui.PromptQuestion() q.title = 'Changed Local Profiles' q.explanation = _('The following local profiles were changed. Would you like to save them?') q.functions = ['CMD_SAVE_CHANGES', 'CMD_SAVE_SELECTED', 'CMD_VIEW_CHANGES', 'CMD_VIEW_CHANGES_CLEAN', 'CMD_ABORT'] q.default = 'CMD_VIEW_CHANGES' q.selected = 0 ans = '' arg = None while ans != 'CMD_SAVE_CHANGES': if not changed: return options = sorted(changed.keys()) q.options = options ans, arg = q.promptUser() q.selected = arg # remember selection which = options[arg] if ans == 'CMD_SAVE_SELECTED': write_profile_ui_feedback(which) reload_base(which) q.selected = 0 # saving the selected profile removes it from the list, therefore reset selection elif ans == 'CMD_VIEW_CHANGES': oldprofile = None if aa[which][which].get('filename', False): oldprofile = aa[which][which]['filename'] else: oldprofile = get_profile_filename_from_attachment(which, True) serialize_options = {} serialize_options['METADATA'] = True newprofile = serialize_profile(aa[which], which, serialize_options) aaui.UI_Changes(oldprofile, newprofile, comments=True) elif ans == 'CMD_VIEW_CHANGES_CLEAN': oldprofile = serialize_profile(original_aa[which], which, '') newprofile = serialize_profile(aa[which], which, '') aaui.UI_Changes(oldprofile, newprofile) for profile_name in sorted(changed.keys()): write_profile_ui_feedback(profile_name) reload_base(profile_name) def get_pager(): return 'less' def set_process(pid, profile): # If process not running don't do anything if not os.path.exists('/proc/%s/attr/current' % pid): return None process = None try: process = open_file_read('/proc/%s/attr/current' % pid) except IOError: return None current = process.readline().strip() process.close() if not re.search('^null(-complain)*-profile$', current): return None stats = None try: stats = open_file_read('/proc/%s/stat' % pid) except IOError: return None stat = stats.readline().strip() stats.close() match = re.search('^\d+ \((\S+)\) ', stat) if not match: return None try: process = open_file_write('/proc/%s/attr/current' % pid) except IOError: return None process.write('setprofile %s' % profile) process.close() def collapse_log(): log_dict = hasher() for aamode in prelog.keys(): for profile in prelog[aamode].keys(): for hat in prelog[aamode][profile].keys(): log_dict[aamode][profile][hat] = ProfileStorage(profile, hat, 'collapse_log()') for path in prelog[aamode][profile][hat]['path'].keys(): mode = prelog[aamode][profile][hat]['path'][path] user, other = split_mode(mode) # logparser.py doesn't preserve 'owner' information, see https://bugs.launchpad.net/apparmor/+bug/1538340 # XXX re-check this code after fixing this bug if other: owner = False mode = other else: owner = True mode = user # python3 aa-logprof -f <(echo '[55826.822365] audit: type=1400 audit(1454355221.096:85479): apparmor="ALLOWED" operation="file_receive" profile="/usr/sbin/smbd" name="/foo.png" pid=28185 comm="smbd" requested_mask="w" denied_mask="w" fsuid=100 ouid=100') # happens via log_str_to_mode() called in logparser.py parse_event_for_tree() # XXX fix this in the log parsing! if 'a' in mode and 'w' in mode: mode.remove('a') file_event = FileRule(path, mode, None, FileRule.ALL, owner=owner, log_event=True) if not is_known_rule(aa[profile][hat], 'file', file_event): log_dict[aamode][profile][hat]['file'].add(file_event) for cap in prelog[aamode][profile][hat]['capability'].keys(): cap_event = CapabilityRule(cap, log_event=True) if not is_known_rule(aa[profile][hat], 'capability', cap_event): log_dict[aamode][profile][hat]['capability'].add(cap_event) dbus = prelog[aamode][profile][hat]['dbus'] for access in dbus: for bus in dbus[access]: for path in dbus[access][bus]: for name in dbus[access][bus][path]: for interface in dbus[access][bus][path][name]: for member in dbus[access][bus][path][name][interface]: for peer_profile in dbus[access][bus][path][name][interface][member]: # Depending on the access type, not all parameters are allowed. # Ignore them, even if some of them appear in the log. # Also, the log doesn't provide a peer name, therefore always use ALL. if access in ['send', 'receive']: dbus_event = DbusRule(access, bus, path, DbusRule.ALL, interface, member, DbusRule.ALL, peer_profile, log_event=True) elif access == 'bind': dbus_event = DbusRule(access, bus, DbusRule.ALL, name, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, log_event=True) elif access == 'eavesdrop': dbus_event = DbusRule(access, bus, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, log_event=True) else: raise AppArmorBug('unexpected dbus access: %s') log_dict[aamode][profile][hat]['dbus'].add(dbus_event) nd = prelog[aamode][profile][hat]['netdomain'] for family in nd.keys(): for sock_type in nd[family].keys(): net_event = NetworkRule(family, sock_type, log_event=True) if not is_known_rule(aa[profile][hat], 'network', net_event): log_dict[aamode][profile][hat]['network'].add(net_event) ptrace = prelog[aamode][profile][hat]['ptrace'] for peer in ptrace.keys(): for access in ptrace[peer].keys(): ptrace_event = PtraceRule(access, peer, log_event=True) if not is_known_rule(aa[profile][hat], 'ptrace', ptrace_event): log_dict[aamode][profile][hat]['ptrace'].add(ptrace_event) sig = prelog[aamode][profile][hat]['signal'] for peer in sig.keys(): for access in sig[peer].keys(): for signal in sig[peer][access].keys(): signal_event = SignalRule(access, signal, peer, log_event=True) if not is_known_rule(aa[profile][hat], 'signal', signal_event): log_dict[aamode][profile][hat]['signal'].add(signal_event) return log_dict def is_skippable_file(path): """Returns True if filename matches something to be skipped (rpm or dpkg backup files, hidden files etc.) The list of skippable files needs to be synced with apparmor initscript and libapparmor _aa_is_blacklisted() path: filename (with or without directory)""" basename = os.path.basename(path) if not basename or basename[0] == '.' or basename == 'README': return True skippable_suffix = ('.dpkg-new', '.dpkg-old', '.dpkg-dist', '.dpkg-bak', '.dpkg-remove', '.pacsave', '.pacnew', '.rpmnew', '.rpmsave', '.orig', '.rej', '~') if basename.endswith(skippable_suffix): return True return False def is_skippable_dir(path): if re.search('^(.*/)?(disable|cache|cache\.d|force-complain|lxc|\.git)/?$', path): return True return False def read_profiles(): # we'll read all profiles from disk, so reset the storage first (autodep() might have created/stored # a profile already, which would cause a 'Conflicting profile' error in attach_profile_data()) global aa, original_aa aa = hasher() original_aa = hasher() try: os.listdir(profile_dir) except: fatal_error(_("Can't read AppArmor profiles in %s") % profile_dir) for file in os.listdir(profile_dir): if os.path.isfile(profile_dir + '/' + file): if is_skippable_file(file): continue else: read_profile(profile_dir + '/' + file, True) def read_inactive_profiles(): if hasattr(read_inactive_profiles, 'already_read'): # each autodep() run calls read_inactive_profiles, but that's a) superfluous and b) triggers a conflict because the inactive profiles are already loaded # therefore don't do anything if the inactive profiles were already loaded return read_inactive_profiles.already_read = True if not os.path.exists(extra_profile_dir): return None try: os.listdir(profile_dir) except: fatal_error(_("Can't read AppArmor profiles in %s") % extra_profile_dir) for file in os.listdir(extra_profile_dir): if os.path.isfile(extra_profile_dir + '/' + file): if is_skippable_file(file): continue else: read_profile(extra_profile_dir + '/' + file, False) def read_profile(file, active_profile): data = None try: with open_file_read(file) as f_in: data = f_in.readlines() except IOError: debug_logger.debug("read_profile: can't read %s - skipping" % file) return None profile_data = parse_profile_data(data, file, 0) if profile_data and active_profile: attach_profile_data(aa, profile_data) attach_profile_data(original_aa, profile_data) for profile in profile_data: # TODO: also honor hats name = profile_data[profile][profile]['name'] attachment = profile_data[profile][profile]['attachment'] filename = profile_data[profile][profile]['filename'] if not attachment and name.startswith('/'): active_profiles.add(filename, name, name) # use name as name and attachment else: active_profiles.add(filename, name, attachment) elif profile_data: attach_profile_data(extras, profile_data) for profile in profile_data: # TODO: also honor hats name = profile_data[profile][profile]['name'] attachment = profile_data[profile][profile]['attachment'] filename = profile_data[profile][profile]['filename'] if not attachment and name.startswith('/'): extra_profiles.add(filename, name, name) # use name as name and attachment else: extra_profiles.add(filename, name, attachment) def attach_profile_data(profiles, profile_data): # Make deep copy of data to avoid changes to # arising due to mutables for p in profile_data.keys(): if profiles.get(p, False): for hat in profile_data[p].keys(): if profiles[p].get(hat, False): raise AppArmorException(_("Conflicting profiles for %s defined in two files:\n- %s\n- %s") % (combine_name(p, hat), profiles[p][hat]['filename'], profile_data[p][hat]['filename'])) profiles[p] = deepcopy(profile_data[p]) def parse_profile_start(line, file, lineno, profile, hat): matches = parse_profile_start_line(line, file) if profile: # we are inside a profile, so we expect a child profile if not matches['profile_keyword']: raise AppArmorException(_('%(profile)s profile in %(file)s contains syntax errors in line %(line)s: missing "profile" keyword.') % { 'profile': profile, 'file': file, 'line': lineno + 1 }) if profile != hat: # nesting limit reached - a child profile can't contain another child profile raise AppArmorException(_('%(profile)s profile in %(file)s contains syntax errors in line %(line)s: a child profile inside another child profile is not allowed.') % { 'profile': profile, 'file': file, 'line': lineno + 1 }) hat = matches['profile'] in_contained_hat = True pps_set_profile = True pps_set_hat_external = False else: # stand-alone profile profile = matches['profile'] if len(profile.split('//')) > 2: raise AppArmorException("Nested child profiles ('%(profile)s', found in %(file)s) are not supported by the AppArmor tools yet." % {'profile': profile, 'file': file}) elif len(profile.split('//')) == 2: profile, hat = profile.split('//') pps_set_hat_external = True else: hat = profile pps_set_hat_external = False in_contained_hat = False pps_set_profile = False attachment = matches['attachment'] flags = matches['flags'] return (profile, hat, attachment, flags, in_contained_hat, pps_set_profile, pps_set_hat_external) def parse_profile_data(data, file, do_include): profile_data = hasher() profile = None hat = None in_contained_hat = None repo_data = None parsed_profiles = [] initial_comment = '' lastline = None if do_include: profile = file hat = file profile_data[profile][hat] = ProfileStorage(profile, hat, 'parse_profile_data() do_include') profile_data[profile][hat]['filename'] = file for lineno, line in enumerate(data): line = line.strip() if not line: continue # we're dealing with a multiline statement if lastline: line = '%s %s' % (lastline, line) lastline = None # Starting line of a profile if RE_PROFILE_START.search(line): (profile, hat, attachment, flags, in_contained_hat, pps_set_profile, pps_set_hat_external) = parse_profile_start(line, file, lineno, profile, hat) if profile_data[profile].get(hat, False): raise AppArmorException('Profile %(profile)s defined twice in %(file)s, last found in line %(line)s' % { 'file': file, 'line': lineno + 1, 'profile': combine_name(profile, hat) }) profile_data[profile][hat] = ProfileStorage(profile, hat, 'parse_profile_data() profile_start') if attachment: profile_data[profile][hat]['attachment'] = attachment if pps_set_profile: profile_data[profile][hat]['profile'] = True if pps_set_hat_external: profile_data[profile][hat]['external'] = True # save profile name and filename profile_data[profile][hat]['name'] = profile profile_data[profile][hat]['filename'] = file filelist[file]['profiles'][profile][hat] = True profile_data[profile][hat]['flags'] = flags # Save the initial comment if initial_comment: profile_data[profile][hat]['initial_comment'] = initial_comment initial_comment = '' if repo_data: profile_data[profile][profile]['repo']['url'] = repo_data['url'] profile_data[profile][profile]['repo']['user'] = repo_data['user'] elif RE_PROFILE_END.search(line): # If profile ends and we're not in one if not profile: raise AppArmorException(_('Syntax Error: Unexpected End of Profile reached in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 }) if in_contained_hat: hat = profile in_contained_hat = False else: parsed_profiles.append(profile) profile = None initial_comment = '' elif CapabilityRule.match(line): if not profile: raise AppArmorException(_('Syntax Error: Unexpected capability entry found in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 }) profile_data[profile][hat]['capability'].add(CapabilityRule.parse(line)) elif RE_PROFILE_LINK.search(line): matches = RE_PROFILE_LINK.search(line).groups() if not profile: raise AppArmorException(_('Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 }) audit = False if matches[0]: audit = True allow = 'allow' if matches[1] and matches[1].strip() == 'deny': allow = 'deny' subset = matches[3] link = strip_quotes(matches[6]) value = strip_quotes(matches[7]) profile_data[profile][hat][allow]['link'][link]['to'] = value profile_data[profile][hat][allow]['link'][link]['mode'] = profile_data[profile][hat][allow]['link'][link].get('mode', set()) | apparmor.aamode.AA_MAY_LINK if subset: profile_data[profile][hat][allow]['link'][link]['mode'] |= apparmor.aamode.AA_LINK_SUBSET if audit: profile_data[profile][hat][allow]['link'][link]['audit'] = profile_data[profile][hat][allow]['link'][link].get('audit', set()) | apparmor.aamode.AA_LINK_SUBSET else: profile_data[profile][hat][allow]['link'][link]['audit'] = set() elif ChangeProfileRule.match(line): if not profile: raise AppArmorException(_('Syntax Error: Unexpected change profile entry found in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 }) profile_data[profile][hat]['change_profile'].add(ChangeProfileRule.parse(line)) elif RE_PROFILE_ALIAS.search(line): matches = RE_PROFILE_ALIAS.search(line).groups() from_name = strip_quotes(matches[0]) to_name = strip_quotes(matches[1]) if profile: profile_data[profile][hat]['alias'][from_name] = to_name else: if not filelist.get(file, False): filelist[file] = hasher() filelist[file]['alias'][from_name] = to_name elif RlimitRule.match(line): if not profile: raise AppArmorException(_('Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 }) profile_data[profile][hat]['rlimit'].add(RlimitRule.parse(line)) elif RE_PROFILE_BOOLEAN.search(line): matches = RE_PROFILE_BOOLEAN.search(line).groups() if profile and not do_include: raise AppArmorException(_('Syntax Error: Unexpected boolean definition found inside profile in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 }) bool_var = matches[0] value = matches[1] profile_data[profile][hat]['lvar'][bool_var] = value elif RE_PROFILE_VARIABLE.search(line): # variable additions += and = matches = RE_PROFILE_VARIABLE.search(line).groups() list_var = strip_quotes(matches[0]) var_operation = matches[1] value = matches[2] if profile: if not profile_data[profile][hat].get('lvar', False): profile_data[profile][hat]['lvar'][list_var] = [] store_list_var(profile_data[profile]['lvar'], list_var, value, var_operation, file) else: if not filelist[file].get('lvar', False): filelist[file]['lvar'][list_var] = [] store_list_var(filelist[file]['lvar'], list_var, value, var_operation, file) elif RE_PROFILE_CONDITIONAL.search(line): # Conditional Boolean pass elif RE_PROFILE_CONDITIONAL_VARIABLE.search(line): # Conditional Variable defines pass elif RE_PROFILE_CONDITIONAL_BOOLEAN.search(line): # Conditional Boolean defined pass elif RE_ABI.search(line): if profile: profile_data[profile][hat]['abi'].append(line) else: if not filelist.get(file): filelist[file] = hasher() if not filelist[file].get('abi'): filelist[file]['abi'] = [] filelist[file]['abi'].append(line) elif re_match_include(line): # Include files include_name = re_match_include(line) if include_name.startswith('local/'): profile_data[profile][hat]['localinclude'][include_name] = True if profile: profile_data[profile][hat]['include'][include_name] = True else: if not filelist.get(file): filelist[file] = hasher() filelist[file]['include'][include_name] = True # If include is a directory if os.path.isdir(get_include_path(include_name)): for file_name in include_dir_filelist(profile_dir, include_name): if not include.get(file_name, False): load_include(file_name) else: if not include.get(include_name, False): load_include(include_name) elif NetworkRule.match(line): if not profile: raise AppArmorException(_('Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 }) profile_data[profile][hat]['network'].add(NetworkRule.parse(line)) elif DbusRule.match(line): if not profile: raise AppArmorException(_('Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s') % {'file': file, 'line': lineno + 1 }) profile_data[profile][hat]['dbus'].add(DbusRule.parse(line)) elif RE_PROFILE_MOUNT.search(line): matches = RE_PROFILE_MOUNT.search(line).groups() if not profile: raise AppArmorException(_('Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 }) audit = False if matches[0]: audit = True allow = 'allow' if matches[1] and matches[1].strip() == 'deny': allow = 'deny' mount = matches[2] mount_rule = parse_mount_rule(mount) mount_rule.audit = audit mount_rule.deny = (allow == 'deny') mount_rules = profile_data[profile][hat][allow].get('mount', list()) mount_rules.append(mount_rule) profile_data[profile][hat][allow]['mount'] = mount_rules elif SignalRule.match(line): if not profile: raise AppArmorException(_('Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 }) profile_data[profile][hat]['signal'].add(SignalRule.parse(line)) elif PtraceRule.match(line): if not profile: raise AppArmorException(_('Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 }) profile_data[profile][hat]['ptrace'].add(PtraceRule.parse(line)) elif RE_PROFILE_PIVOT_ROOT.search(line): matches = RE_PROFILE_PIVOT_ROOT.search(line).groups() if not profile: raise AppArmorException(_('Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 }) audit = False if matches[0]: audit = True allow = 'allow' if matches[1] and matches[1].strip() == 'deny': allow = 'deny' pivot_root = matches[2].strip() pivot_root_rule = parse_pivot_root_rule(pivot_root) pivot_root_rule.audit = audit pivot_root_rule.deny = (allow == 'deny') pivot_root_rules = profile_data[profile][hat][allow].get('pivot_root', list()) pivot_root_rules.append(pivot_root_rule) profile_data[profile][hat][allow]['pivot_root'] = pivot_root_rules elif RE_PROFILE_UNIX.search(line): matches = RE_PROFILE_UNIX.search(line).groups() if not profile: raise AppArmorException(_('Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 }) audit = False if matches[0]: audit = True allow = 'allow' if matches[1] and matches[1].strip() == 'deny': allow = 'deny' unix = matches[2].strip() unix_rule = parse_unix_rule(unix) unix_rule.audit = audit unix_rule.deny = (allow == 'deny') unix_rules = profile_data[profile][hat][allow].get('unix', list()) unix_rules.append(unix_rule) profile_data[profile][hat][allow]['unix'] = unix_rules elif RE_PROFILE_CHANGE_HAT.search(line): matches = RE_PROFILE_CHANGE_HAT.search(line).groups() if not profile: raise AppArmorException(_('Syntax Error: Unexpected change hat declaration found in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 }) aaui.UI_Important(_('Ignoring no longer supported change hat declaration "^%(hat)s," found in file: %(file)s line: %(line)s') % { 'hat': matches[0], 'file': file, 'line': lineno + 1 }) elif RE_PROFILE_HAT_DEF.search(line): # An embedded hat syntax definition starts matches = RE_PROFILE_HAT_DEF.search(line) if not profile: raise AppArmorException(_('Syntax Error: Unexpected hat definition found in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 }) in_contained_hat = True hat = matches.group('hat') hat = strip_quotes(hat) # if hat is already known, the filelist check some lines below will error out. # nevertheless, just to be sure, don't overwrite existing profile_data. if not profile_data[profile].get(hat, False): profile_data[profile][hat] = ProfileStorage(profile, hat, 'parse_profile_data() hat_def') profile_data[profile][hat]['filename'] = file flags = matches.group('flags') profile_data[profile][hat]['flags'] = flags if initial_comment: profile_data[profile][hat]['initial_comment'] = initial_comment initial_comment = '' if filelist[file]['profiles'][profile].get(hat, False) and not do_include: raise AppArmorException(_('Error: Multiple definitions for hat %(hat)s in profile %(profile)s.') % { 'hat': hat, 'profile': profile }) filelist[file]['profiles'][profile][hat] = True elif line[0] == '#': # Handle initial comments if not profile: if line.startswith('# Last Modified:'): continue elif line.startswith('# REPOSITORY:'): # TODO: allow any number of spaces/tabs parts = line.split() if len(parts) == 3 and parts[2] == 'NEVERSUBMIT': repo_data = {'neversubmit': True} elif len(parts) == 5: repo_data = {'url': parts[2], 'user': parts[3], 'id': parts[4]} else: aaui.UI_Important(_('Warning: invalid "REPOSITORY:" line in %s, ignoring.') % file) initial_comment = initial_comment + line + '\n' else: initial_comment = initial_comment + line + '\n' elif FileRule.match(line): # leading permissions could look like a keyword, therefore handle file rules after everything else if not profile: raise AppArmorException(_('Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 }) profile_data[profile][hat]['file'].add(FileRule.parse(line)) elif not RE_RULE_HAS_COMMA.search(line): # Bah, line continues on to the next line if RE_HAS_COMMENT_SPLIT.search(line): # filter trailing comments lastline = RE_HAS_COMMENT_SPLIT.search(line).group('not_comment') else: lastline = line else: raise AppArmorException(_('Syntax Error: Unknown line found in file %(file)s line %(lineno)s:\n %(line)s') % { 'file': file, 'lineno': lineno + 1, 'line': line }) if lastline: # lastline gets merged into line (and reset to None) when reading the next line. # If it isn't empty, this means there's something unparseable at the end of the profile raise AppArmorException(_('Syntax Error: Unknown line found in file %(file)s line %(lineno)s:\n %(line)s') % { 'file': file, 'lineno': lineno + 1, 'line': lastline }) # Below is not required I'd say if not do_include: for hatglob in cfg['required_hats'].keys(): for parsed_prof in sorted(parsed_profiles): if re.search(hatglob, parsed_prof): for hat in cfg['required_hats'][hatglob].split(): if not profile_data[parsed_prof].get(hat, False): profile_data[parsed_prof][hat] = ProfileStorage(parsed_prof, hat, 'parse_profile_data() required_hats') # End of file reached but we're stuck in a profile if profile and not do_include: raise AppArmorException(_("Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside profile %(profile)s") % { 'file': file, 'profile': profile }) return profile_data def parse_mount_rule(line): # XXX Do real parsing here return aarules.Raw_Mount_Rule(line) def parse_pivot_root_rule(line): # XXX Do real parsing here return aarules.Raw_Pivot_Root_Rule(line) def parse_unix_rule(line): # XXX Do real parsing here return aarules.Raw_Unix_Rule(line) def separate_vars(vs): """Returns a list of all the values for a variable""" data = set() vs = vs.strip() RE_VARS = re.compile('^(("[^"]*")|([^"\s]+))\s*(.*)$') while RE_VARS.search(vs): matches = RE_VARS.search(vs).groups() data.add(strip_quotes(matches[0])) vs = matches[3].strip() if vs: raise AppArmorException('Variable assignments contains invalid parts (unbalanced quotes?): %s' % vs) return data def is_active_profile(pname): if aa.get(pname, False): return True else: return False def store_list_var(var, list_var, value, var_operation, filename): """Store(add new variable or add values to variable) the variables encountered in the given list_var - the 'var' parameter will be modified - 'list_var' is the variable name, for example '@{foo}' """ vlist = separate_vars(value) if var_operation == '=': if not var.get(list_var, False): var[list_var] = set(vlist) else: raise AppArmorException(_('Redefining existing variable %(variable)s: %(value)s in %(file)s') % { 'variable': list_var, 'value': value, 'file': filename }) elif var_operation == '+=': if var.get(list_var, False): var[list_var] |= vlist else: raise AppArmorException(_('Values added to a non-existing variable %(variable)s: %(value)s in %(file)s') % { 'variable': list_var, 'value': value, 'file': filename }) else: raise AppArmorException(_('Unknown variable operation %(operation)s for variable %(variable)s in %(file)s') % { 'operation': var_operation, 'variable': list_var, 'file': filename }) def write_header(prof_data, depth, name, embedded_hat, write_flags): pre = ' ' * int(depth * 2) data = [] unquoted_name = name name = quote_if_needed(name) attachment = '' if prof_data['attachment']: attachment = ' %s' % quote_if_needed(prof_data['attachment']) comment = '' if prof_data['header_comment']: comment = ' %s' % prof_data['header_comment'] if (not embedded_hat and re.search('^[^/]', unquoted_name)) or (embedded_hat and re.search('^[^^]', unquoted_name)) or prof_data['attachment'] or prof_data['profile_keyword']: name = 'profile %s%s' % (name, attachment) flags = '' if write_flags and prof_data['flags']: flags = ' flags=(%s)' % prof_data['flags'] data.append('%s%s%s {%s' % (pre, name, flags, comment)) return data def set_allow_str(allow): if allow == 'deny': return 'deny ' elif allow == 'allow': return '' elif allow == '': return '' else: raise AppArmorException(_("Invalid allow string: %(allow)s")) def set_ref_allow(prof_data, allow): if allow: return prof_data[allow], set_allow_str(allow) else: return prof_data, '' def write_pair(prof_data, depth, allow, name, prefix, sep, tail, fn): pre = ' ' * depth data = [] ref, allow = set_ref_allow(prof_data, allow) if ref.get(name, False): for key in sorted(ref[name].keys()): value = fn(ref[name][key]) # eval('%s(%s)' % (fn, ref[name][key])) data.append('%s%s%s%s%s%s%s' % (pre, allow, prefix, key, sep, value, tail)) if ref[name].keys(): data.append('') return data def write_includes(prof_data, depth): pre = ' ' * depth data = [] for key in sorted(prof_data['include'].keys()): if key.startswith('/'): qkey = '"%s"' % key else: qkey = '<%s>' % quote_if_needed(key) data.append('%s#include %s' % (pre, qkey)) if data: data.append('') return data def write_change_profile(prof_data, depth): data = [] if prof_data.get('change_profile', False): data = prof_data['change_profile'].get_clean(depth) return data def write_alias(prof_data, depth): return write_pair(prof_data, depth, '', 'alias', 'alias ', ' -> ', ',', quote_if_needed) def write_rlimits(prof_data, depth): data = [] if prof_data.get('rlimit', False): data = prof_data['rlimit'].get_clean(depth) return data def var_transform(ref): data = [] for value in ref: if not value: value = '""' data.append(quote_if_needed(value)) return ' '.join(data) def write_list_vars(prof_data, depth): return write_pair(prof_data, depth, '', 'lvar', '', ' = ', '', var_transform) def write_capabilities(prof_data, depth): data = [] if prof_data.get('capability', False): data = prof_data['capability'].get_clean(depth) return data def write_netdomain(prof_data, depth): data = [] if prof_data.get('network', False): data = prof_data['network'].get_clean(depth) return data def write_dbus(prof_data, depth): data = [] if prof_data.get('dbus', False): data = prof_data['dbus'].get_clean(depth) return data def write_mount_rules(prof_data, depth, allow): pre = ' ' * depth data = [] # no mount rules, so return if not prof_data[allow].get('mount', False): return data for mount_rule in prof_data[allow]['mount']: data.append('%s%s' % (pre, mount_rule.serialize())) data.append('') return data def write_mount(prof_data, depth): data = write_mount_rules(prof_data, depth, 'deny') data += write_mount_rules(prof_data, depth, 'allow') return data def write_signal(prof_data, depth): data = [] if prof_data.get('signal', False): data = prof_data['signal'].get_clean(depth) return data def write_ptrace(prof_data, depth): data = [] if prof_data.get('ptrace', False): data = prof_data['ptrace'].get_clean(depth) return data def write_pivot_root_rules(prof_data, depth, allow): pre = ' ' * depth data = [] # no pivot_root rules, so return if not prof_data[allow].get('pivot_root', False): return data for pivot_root_rule in prof_data[allow]['pivot_root']: data.append('%s%s' % (pre, pivot_root_rule.serialize())) data.append('') return data def write_pivot_root(prof_data, depth): data = write_pivot_root_rules(prof_data, depth, 'deny') data += write_pivot_root_rules(prof_data, depth, 'allow') return data def write_unix_rules(prof_data, depth, allow): pre = ' ' * depth data = [] # no unix rules, so return if not prof_data[allow].get('unix', False): return data for unix_rule in prof_data[allow]['unix']: data.append('%s%s' % (pre, unix_rule.serialize())) data.append('') return data def write_unix(prof_data, depth): data = write_unix_rules(prof_data, depth, 'deny') data += write_unix_rules(prof_data, depth, 'allow') return data def write_link_rules(prof_data, depth, allow): pre = ' ' * depth data = [] allowstr = set_allow_str(allow) if prof_data[allow].get('link', False): for path in sorted(prof_data[allow]['link'].keys()): to_name = prof_data[allow]['link'][path]['to'] subset = '' if prof_data[allow]['link'][path]['mode'] & apparmor.aamode.AA_LINK_SUBSET: subset = 'subset ' audit = '' if prof_data[allow]['link'][path].get('audit', False): audit = 'audit ' path = quote_if_needed(path) to_name = quote_if_needed(to_name) data.append('%s%s%slink %s%s -> %s,' % (pre, audit, allowstr, subset, path, to_name)) data.append('') return data def write_links(prof_data, depth): data = write_link_rules(prof_data, depth, 'deny') data += write_link_rules(prof_data, depth, 'allow') return data def write_file(prof_data, depth): data = [] if prof_data.get('file', False): data = prof_data['file'].get_clean(depth) return data def write_rules(prof_data, depth): data = write_abi(prof_data, depth) data += write_alias(prof_data, depth) data += write_list_vars(prof_data, depth) data += write_includes(prof_data, depth) data += write_rlimits(prof_data, depth) data += write_capabilities(prof_data, depth) data += write_netdomain(prof_data, depth) data += write_dbus(prof_data, depth) data += write_mount(prof_data, depth) data += write_signal(prof_data, depth) data += write_ptrace(prof_data, depth) data += write_pivot_root(prof_data, depth) data += write_unix(prof_data, depth) data += write_links(prof_data, depth) data += write_file(prof_data, depth) data += write_change_profile(prof_data, depth) return data def write_piece(profile_data, depth, name, nhat, write_flags): pre = ' ' * depth data = [] wname = None inhat = False if name == nhat: wname = name else: wname = name + '//' + nhat name = nhat inhat = True data += write_header(profile_data[name], depth, wname, False, write_flags) data += write_rules(profile_data[name], depth + 1) pre2 = ' ' * (depth + 1) if not inhat: # Embedded hats for hat in list(filter(lambda x: x != name, sorted(profile_data.keys()))): if not profile_data[hat]['external']: data.append('') if profile_data[hat]['profile']: data += list(map(str, write_header(profile_data[hat], depth + 1, hat, True, write_flags))) else: data += list(map(str, write_header(profile_data[hat], depth + 1, '^' + hat, True, write_flags))) data += list(map(str, write_rules(profile_data[hat], depth + 2))) data.append('%s}' % pre2) data.append('%s}' % pre) # External hats for hat in list(filter(lambda x: x != name, sorted(profile_data.keys()))): if name == nhat and profile_data[hat].get('external', False): data.append('') data += list(map(lambda x: ' %s' % x, write_piece(profile_data, depth - 1, name, nhat, write_flags))) data.append(' }') return data def serialize_profile(profile_data, name, options): string = '' include_metadata = False include_flags = True data = [] if options: # and type(options) == dict: if options.get('METADATA', False): include_metadata = True if options.get('NO_FLAGS', False): include_flags = False if include_metadata: string = '# Last Modified: %s\n' % time.asctime() if (profile_data[name].get('repo', False) and profile_data[name]['repo']['url'] and profile_data[name]['repo']['user'] and profile_data[name]['repo']['id']): repo = profile_data[name]['repo'] string += '# REPOSITORY: %s %s %s\n' % (repo['url'], repo['user'], repo['id']) elif profile_data[name]['repo'].get('neversubmit'): string += '# REPOSITORY: NEVERSUBMIT\n' # if profile_data[name].get('initial_comment', False): # comment = profile_data[name]['initial_comment'] # comment.replace('\\n', '\n') # string += comment + '\n' if options and options.get('is_attachment'): prof_filename = get_profile_filename_from_attachment(name, True) else: prof_filename = get_profile_filename_from_profile_name(name, True) if filelist.get(prof_filename, False): data += write_abi(filelist[prof_filename], 0) data += write_alias(filelist[prof_filename], 0) data += write_list_vars(filelist[prof_filename], 0) data += write_includes(filelist[prof_filename], 0) #Here should be all the profiles from the files added write after global/common stuff for prof in sorted(filelist[prof_filename]['profiles'].keys()): if prof != name: if original_aa[prof][prof].get('initial_comment', False): comment = original_aa[prof][prof]['initial_comment'] comment.replace('\\n', '\n') data += [comment + '\n'] data += write_piece(original_aa[prof], 0, prof, prof, include_flags) else: if profile_data[name].get('initial_comment', False): comment = profile_data[name]['initial_comment'] comment.replace('\\n', '\n') data += [comment + '\n'] data += write_piece(profile_data, 0, name, name, include_flags) string += '\n'.join(data) return string + '\n' def serialize_parse_profile_start(line, file, lineno, profile, hat, prof_data_profile, prof_data_external, correct): (profile, hat, attachment, flags, in_contained_hat, pps_set_profile, pps_set_hat_external) = parse_profile_start(line, file, lineno, profile, hat) if hat and profile != hat and '%s//%s'%(profile, hat) in line and not prof_data_external: correct = False return (profile, hat, attachment, flags, in_contained_hat, correct) def write_profile_ui_feedback(profile, is_attachment=False): aaui.UI_Info(_('Writing updated profile for %s.') % profile) write_profile(profile, is_attachment) def write_profile(profile, is_attachment=False): prof_filename = None if aa[profile][profile].get('filename', False): prof_filename = aa[profile][profile]['filename'] elif is_attachment: prof_filename = get_profile_filename_from_attachment(profile, True) else: prof_filename = get_profile_filename_from_profile_name(profile, True) newprof = tempfile.NamedTemporaryFile('w', suffix='~', delete=False, dir=profile_dir) if os.path.exists(prof_filename): shutil.copymode(prof_filename, newprof.name) else: #permission_600 = stat.S_IRUSR | stat.S_IWUSR # Owner read and write #os.chmod(newprof.name, permission_600) pass serialize_options = {'METADATA': True, 'is_attachment': is_attachment} profile_string = serialize_profile(aa[profile], profile, serialize_options) newprof.write(profile_string) newprof.close() os.rename(newprof.name, prof_filename) if profile in changed: changed.pop(profile) else: debug_logger.info("Unchanged profile written: %s (not listed in 'changed' list)" % profile) original_aa[profile] = deepcopy(aa[profile]) def is_known_rule(profile, rule_type, rule_obj): # XXX get rid of get() checks after we have a proper function to initialize a profile if profile.get(rule_type, False): if profile[rule_type].is_covered(rule_obj, False): return True includelist = list(profile['include'].keys()) checked = [] while includelist: incname = includelist.pop(0) checked.append(incname) if os.path.isdir(get_include_path(incname)): includelist += include_dir_filelist(profile_dir, incname) else: if include[incname][incname].get(rule_type, False): if include[incname][incname][rule_type].is_covered(rule_obj, False): return True for childinc in include[incname][incname]['include'].keys(): if childinc not in checked: includelist += [childinc] return False def get_file_perms(profile, path, audit, deny): '''get the current permissions for the given path''' perms = profile['file'].get_perms_for_path(path, audit, deny) includelist = list(profile['include'].keys()) checked = [] while includelist: incname = includelist.pop(0) if incname in checked: continue checked.append(incname) if os.path.isdir(get_include_path(incname)): includelist += include_dir_filelist(profile_dir, incname) else: incperms = include[incname][incname]['file'].get_perms_for_path(path, audit, deny) for allow_or_deny in ['allow', 'deny']: for owner_or_all in ['all', 'owner']: for perm in incperms[allow_or_deny][owner_or_all]: perms[allow_or_deny][owner_or_all].add(perm) if 'a' in perms[allow_or_deny][owner_or_all] and 'w' in perms[allow_or_deny][owner_or_all]: perms[allow_or_deny][owner_or_all].remove('a') # a is a subset of w, so remove it for incpath in incperms['paths']: perms['paths'].add(incpath) for childinc in include[incname][incname]['include'].keys(): if childinc not in checked: includelist += [childinc] return perms def propose_file_rules(profile_obj, rule_obj): '''Propose merged file rules based on the existing profile and the log events - permissions get merged - matching paths from existing rules, common_glob() and user_globs get proposed - IMPORTANT: modifies rule_obj.original_perms and rule_obj.perms''' options = [] original_path = rule_obj.path.regex merged_rule_obj = deepcopy(rule_obj) # make sure not to modify the original rule object (with exceptions, see end of this function) existing_perms = get_file_perms(profile_obj, rule_obj.path, False, False) for perm in existing_perms['allow']['all']: # XXX also handle owner-only perms merged_rule_obj.perms.add(perm) merged_rule_obj.raw_rule = None if 'a' in merged_rule_obj.perms and 'w' in merged_rule_obj.perms: merged_rule_obj.perms.remove('a') # a is a subset of w, so remove it pathlist = {original_path} | existing_perms['paths'] | set(glob_common(original_path)) for user_glob in user_globs: if user_globs[user_glob].match(original_path): pathlist.add(user_glob) pathlist = order_globs(pathlist, original_path) # paths in existing rules that match the original path for path in pathlist: merged_rule_obj.store_edit(path) merged_rule_obj.raw_rule = None options.append(merged_rule_obj.get_clean()) merged_rule_obj.exec_perms = None rule_obj.original_perms = existing_perms if rule_obj.perms != merged_rule_obj.perms: rule_obj.perms = merged_rule_obj.perms rule_obj.raw_rule = None return options def reload_base(bin_path): if not check_for_apparmor(): return None prof_filename = get_profile_filename_from_profile_name(bin_path, True) # XXX use reload_profile() from tools.py instead (and don't hide output in /dev/null) subprocess.call("cat '%s' | %s -I%s -r >/dev/null 2>&1" % (prof_filename, parser, profile_dir), shell=True) def reload(bin_path): bin_path = find_executable(bin_path) if not bin_path: return None return reload_base(bin_path) def get_include_data(filename): data = [] if not filename.startswith('/'): filename = profile_dir + '/' + filename if os.path.exists(filename): with open_file_read(filename) as f_in: data = f_in.readlines() else: raise AppArmorException(_('File Not Found: %s') % filename) return data def include_dir_filelist(profile_dir, include_name): '''returns a list of files in the given profile_dir/include_name directory, except skippable files. If include_name is an absolute path, ignore profile_dir. ''' files = [] include_name_abs = get_include_path(include_name) for path in os.listdir(include_name_abs): path = path.strip() if is_skippable_file(path): continue if os.path.isfile(include_name_abs + '/' + path): file_name = include_name + '/' + path # strip off profile_dir for non-absolute paths if not include_name.startswith('/'): file_name = file_name.replace(profile_dir + '/', '') files.append(file_name) return files def load_include(incname): load_includeslist = [incname] while load_includeslist: incfile = load_includeslist.pop(0) incfile_abs = get_include_path(incfile) if include.get(incfile, {}).get(incfile, False): pass # already read, do nothing elif os.path.isfile(incfile_abs): data = get_include_data(incfile_abs) incdata = parse_profile_data(data, incfile, True) attach_profile_data(include, incdata) #If the include is a directory means include all subfiles elif os.path.isdir(incfile_abs): load_includeslist += include_dir_filelist(profile_dir, incfile) else: raise AppArmorException("Include file %s not found" % (incfile_abs)) return 0 def check_qualifiers(program): if cfg['qualifiers'].get(program, False): if cfg['qualifiers'][program] != 'p': fatal_error(_("%s is currently marked as a program that should not have its own\nprofile. Usually, programs are marked this way if creating a profile for \nthem is likely to break the rest of the system. If you know what you\'re\ndoing and are certain you want to create a profile for this program, edit\nthe corresponding entry in the [qualifiers] section in /etc/apparmor/logprof.conf.") % program) return False def get_subdirectories(current_dir): """Returns a list of all directories directly inside given directory""" if sys.version_info < (3, 0): return os.walk(current_dir).next()[1] else: return os.walk(current_dir).__next__()[1] def loadincludes(): incdirs = get_subdirectories(profile_dir) for idir in incdirs: if is_skippable_dir(idir): continue for dirpath, dirname, files in os.walk(profile_dir + '/' + idir): if is_skippable_dir(dirpath): continue for fi in files: if is_skippable_file(fi): continue else: fi = dirpath + '/' + fi fi = fi.replace(profile_dir + '/', '', 1) load_include(fi) def glob_common(path): globs = [] if re.search('[\d\.]+\.so$', path) or re.search('\.so\.[\d\.]+$', path): libpath = path libpath = re.sub('[\d\.]+\.so$', '*.so', libpath) libpath = re.sub('\.so\.[\d\.]+$', '.so.*', libpath) if libpath != path: globs.append(libpath) for glob in cfg['globs']: if re.search(glob, path): globbedpath = path globbedpath = re.sub(glob, cfg['globs'][glob], path) if globbedpath != path: globs.append(globbedpath) return sorted(set(globs)) def combine_name(name1, name2): if name1 == name2: return name1 else: return '%s^%s' % (name1, name2) def logger_path(): logger = conf.find_first_file(cfg['settings']['logger']) or '/bin/logger' if not os.path.isfile(logger) or not os.access(logger, os.EX_OK): raise AppArmorException("Can't find logger!\nPlease make sure %s exists, or update the 'logger' path in logprof.conf." % logger) return logger ######Initialisations###### def init_aa(confdir="/etc/apparmor"): global CONFDIR global conf global cfg global profile_dir global extra_profile_dir global parser if CONFDIR: return # config already initialized (and possibly changed afterwards), so don't overwrite the config variables CONFDIR = confdir conf = apparmor.config.Config('ini', CONFDIR) cfg = conf.read_config('logprof.conf') # prevent various failures if logprof.conf doesn't exist if not cfg.sections(): cfg.add_section('settings') cfg.add_section('required_hats') if cfg['settings'].get('default_owner_prompt', False): cfg['settings']['default_owner_prompt'] = '' profile_dir = conf.find_first_dir(cfg['settings'].get('profiledir')) or '/etc/apparmor.d' if not os.path.isdir(profile_dir): raise AppArmorException('Can\'t find AppArmor profiles in %s' % (profile_dir)) extra_profile_dir = conf.find_first_dir(cfg['settings'].get('inactive_profiledir')) or '/usr/share/apparmor/extra-profiles/' parser = conf.find_first_file(cfg['settings'].get('parser')) or '/sbin/apparmor_parser' if not os.path.isfile(parser) or not os.access(parser, os.EX_OK): raise AppArmorException('Can\'t find apparmor_parser at %s' % (parser)) apparmor-2.13.3/utils/apparmor/rules.py0000644000175000017500000000212513502024172015672 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ class _Raw_Rule(object): audit = False deny = False def __init__(self, rule): self.rule = rule def serialize(self): return "%s%s%s" % ('audit ' if self.audit else '', 'deny ' if self.deny else '', self.rule) def recursive_print(self, depth): tabs = ' ' * depth * 4 print('%s[%s]' % (tabs, type(self).__name__)) tabs += ' ' * 4 print('%saudit = %s' % (tabs, self.audit)) print('%sdeny = %s' % (tabs, self.deny)) print('%sraw rule = %s' % (tabs, self.rule)) class Raw_Mount_Rule(_Raw_Rule): pass class Raw_Pivot_Root_Rule(_Raw_Rule): pass class Raw_Unix_Rule(_Raw_Rule): pass apparmor-2.13.3/utils/apparmor/__init__.py0000644000175000017500000000057513502024172016306 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2011-2012 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ apparmor-2.13.3/utils/apparmor/aamode.py0000644000175000017500000001207313502024172015771 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import re from apparmor.common import AppArmorBug def AA_OTHER(mode): other = set() for i in mode: other.add('::%s' % i) return other def AA_OTHER_REMOVE(mode): other = set() for i in mode: if '::' in i: other.add(i[2:]) return other AA_MAY_EXEC = set('x') AA_MAY_WRITE = set('w') AA_MAY_READ = set('r') AA_MAY_APPEND = set('a') AA_MAY_LINK = set('l') AA_MAY_LOCK = set('k') AA_EXEC_MMAP = set('m') AA_EXEC_UNSAFE = set(['execunsafe']) AA_EXEC_INHERIT = set('i') AA_EXEC_UNCONFINED = set('U') AA_EXEC_PROFILE = set('P') AA_EXEC_CHILD = set('C') AA_EXEC_NT = set('N') AA_LINK_SUBSET = set(['linksubset']) AA_BARE_FILE_MODE = set(['bare_file_mode']) #AA_OTHER_SHIFT = 14 #AA_USER_MASK = 16384 - 1 MODE_HASH = {'x': AA_MAY_EXEC, 'X': AA_MAY_EXEC, 'w': AA_MAY_WRITE, 'W': AA_MAY_WRITE, 'r': AA_MAY_READ, 'R': AA_MAY_READ, 'a': AA_MAY_APPEND, 'A': AA_MAY_APPEND, 'l': AA_MAY_LINK, 'L': AA_MAY_LINK, 'k': AA_MAY_LOCK, 'K': AA_MAY_LOCK, 'm': AA_EXEC_MMAP, 'M': AA_EXEC_MMAP, 'i': AA_EXEC_INHERIT, 'I': AA_EXEC_INHERIT, 'u': AA_EXEC_UNCONFINED | AA_EXEC_UNSAFE, # Unconfined + Unsafe 'U': AA_EXEC_UNCONFINED, 'p': AA_EXEC_PROFILE | AA_EXEC_UNSAFE, # Profile + unsafe 'P': AA_EXEC_PROFILE, 'c': AA_EXEC_CHILD | AA_EXEC_UNSAFE, # Child + Unsafe 'C': AA_EXEC_CHILD, 'n': AA_EXEC_NT | AA_EXEC_UNSAFE, 'N': AA_EXEC_NT } LOG_MODE_RE = re.compile('^(r|w|l|m|k|a|x|ix|ux|px|pux|cx|nx|pix|cix|Ux|Px|PUx|Cx|Nx|Pix|Cix)+$') MODE_MAP_SET = {"r", "w", "l", "m", "k", "a", "x", "i", "u", "p", "c", "n", "I", "U", "P", "C", "N"} def str_to_mode(string): if not string: return set() user, other = split_log_mode(string) if not user: user = other mode = sub_str_to_mode(user) #print(string, mode) #print(string, 'other', sub_str_to_mode(other)) mode |= (AA_OTHER(sub_str_to_mode(other))) #print (string, mode) #print('str_to_mode:', mode) return mode def sub_str_to_mode(string): mode = set() for mode_char in string: if mode_char in MODE_MAP_SET and MODE_HASH.get(mode_char, False): mode |= MODE_HASH[mode_char] else: raise AppArmorBug("Mode string '%s' contains invalid char '%s'" % (string, mode_char)) return mode def split_log_mode(mode): #if the mode has a "::", then the left side is the user mode, and the right side is the other mode #if not, then the mode is both the user and other mode user = '' other = '' if "::" in mode: try: user, other = mode.split("::") except ValueError as e: raise AppArmorBug("Got ValueError '%s' when splitting %s" % (str(e), mode)) else: user = mode other = mode return user, other def mode_contains(mode, subset): # w implies a if mode & AA_MAY_WRITE: mode |= AA_MAY_APPEND if mode & (AA_OTHER(AA_MAY_WRITE)): mode |= (AA_OTHER(AA_MAY_APPEND)) return (mode & subset) == subset def validate_log_mode(mode): if LOG_MODE_RE.search(mode): return True else: return False def hide_log_mode(mode): mode = mode.replace('::', '') return mode def split_mode(mode): user = set() for i in mode: if not '::' in i: user.add(i) other = mode - user other = AA_OTHER_REMOVE(other) return user, other def log_str_to_mode(profile, string, nt_name): mode = str_to_mode(string) # If contains nx and nix #print (profile, string, nt_name) if mode_contains(mode, str_to_mode('Nx')): # Transform to px, cx match = re.search('(.+?)//(.+?)', nt_name) if match: lprofile, lhat = match.groups() tmode = 0 if lprofile == profile: if mode & AA_MAY_EXEC: tmode = str_to_mode('Cx::') if mode & AA_OTHER(AA_MAY_EXEC): tmode |= str_to_mode('Cx') nt_name = lhat else: if mode & AA_MAY_EXEC: tmode = str_to_mode('Px::') if mode & AA_OTHER(AA_MAY_EXEC): tmode |= str_to_mode('Px') nt_name = lhat mode = mode - str_to_mode('Nx') mode |= tmode return mode, nt_name apparmor-2.13.3/utils/apparmor/cleanprofile.py0000644000175000017500000000724713502024172017215 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2014-2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import apparmor.aa as apparmor class Prof(object): def __init__(self, filename): apparmor.init_aa() self.aa = apparmor.aa self.filelist = apparmor.filelist self.include = apparmor.include self.filename = filename class CleanProf(object): def __init__(self, same_file, profile, other): #If same_file we're basically comparing the file against itself to check superfluous rules self.same_file = same_file self.profile = profile self.other = other def compare_profiles(self): deleted = 0 other_file_includes = list(self.other.filelist[self.other.filename]['include'].keys()) #Remove the duplicate file-level includes from other for rule in self.profile.filelist[self.profile.filename]['include'].keys(): if rule in other_file_includes: self.other.filelist[self.other.filename]['include'].pop(rule) for profile in self.profile.aa.keys(): deleted += self.remove_duplicate_rules(profile) return deleted def remove_duplicate_rules(self, program): #Process the profile of the program #Process every hat in the profile individually file_includes = list(self.profile.filelist[self.profile.filename]['include'].keys()) deleted = 0 for hat in sorted(self.profile.aa[program].keys()): #The combined list of includes from profile and the file includes = list(self.profile.aa[program][hat]['include'].keys()) + file_includes #If different files remove duplicate includes in the other profile if not self.same_file: if self.other.aa[program].get(hat): # carefully avoid to accidently initialize self.other.aa[program][hat] for inc in includes: if self.other.aa[program][hat]['include'].get(inc, False): self.other.aa[program][hat]['include'].pop(inc) deleted += 1 #Clean up superfluous rules from includes in the other profile for inc in includes: if not self.profile.include.get(inc, {}).get(inc, False): apparmor.load_include(inc) if self.other.aa[program].get(hat): # carefully avoid to accidently initialize self.other.aa[program][hat] deleted += apparmor.delete_duplicates(self.other.aa[program][hat], inc) #Clean duplicate rules in other profile for ruletype in apparmor.ruletypes: if not self.same_file: if self.other.aa[program].get(hat): # carefully avoid to accidently initialize self.other.aa[program][hat] deleted += self.other.aa[program][hat][ruletype].delete_duplicates(self.profile.aa[program][hat][ruletype]) else: deleted += self.other.aa[program][hat][ruletype].delete_duplicates(None) return deleted apparmor-2.13.3/utils/apparmor/tools.py0000644000175000017500000002534513502024172015711 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2015-2018 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import os import sys import apparmor.aa as apparmor import apparmor.ui as aaui from apparmor.common import user_perm, cmd # setup module translations from apparmor.translations import init_translation _ = init_translation() class aa_tools: def __init__(self, tool_name, args): apparmor.init_aa() self.name = tool_name self.profiledir = args.dir self.profiling = args.program self.check_profile_dir() self.silent = None self.do_reload = args.do_reload if tool_name in ['audit']: self.remove = args.remove elif tool_name == 'autodep': self.force = args.force self.aa_mountpoint = apparmor.check_for_apparmor() elif tool_name == 'cleanprof': self.silent = args.silent def check_profile_dir(self): if self.profiledir: apparmor.profile_dir = apparmor.get_full_path(self.profiledir) if not os.path.isdir(apparmor.profile_dir): raise apparmor.AppArmorException("%s is not a directory." % self.profiledir) if not user_perm(apparmor.profile_dir): raise apparmor.AppArmorException("Cannot write to profile directory: %s" % (apparmor.profile_dir)) def get_next_to_profile(self): '''Iterator function to walk the list of arguments passed''' for p in self.profiling: if not p: continue program = None profile = None if os.path.exists(p) or p.startswith('/'): fq_path = apparmor.get_full_path(p).strip() if os.path.commonprefix([apparmor.profile_dir, fq_path]) == apparmor.profile_dir: program = None profile = fq_path else: program = fq_path profile = apparmor.get_profile_filename_from_attachment(fq_path, True) else: which = apparmor.which(p) if which is not None: program = apparmor.get_full_path(which) profile = apparmor.get_profile_filename_from_attachment(program, True) elif os.path.exists(os.path.join(apparmor.profile_dir, p)): program = None profile = apparmor.get_full_path(os.path.join(apparmor.profile_dir, p)).strip() else: if '/' not in p: aaui.UI_Info(_("Can't find %(program)s in the system path list. If the name of the application\nis correct, please run 'which %(program)s' as a user with correct PATH\nenvironment set up in order to find the fully-qualified path and\nuse the full path as parameter.") % { 'program': p }) else: aaui.UI_Info(_("%s does not exist, please double-check the path.") % p) continue yield (program, profile) def cleanprof_act(self): # used by aa-cleanprof apparmor.read_profiles() for (program, profile) in self.get_next_to_profile(): if program is None: program = profile if not program or not(os.path.exists(program) or apparmor.profile_exists(program)): if program and not program.startswith('/'): program = aaui.UI_GetString(_('The given program cannot be found, please try with the fully qualified path name of the program: '), '') else: aaui.UI_Info(_("%s does not exist, please double-check the path.") % program) sys.exit(1) if program and apparmor.profile_exists(program): self.clean_profile(program) else: if '/' not in program: aaui.UI_Info(_("Can't find %(program)s in the system path list. If the name of the application\nis correct, please run 'which %(program)s' as a user with correct PATH\nenvironment set up in order to find the fully-qualified path and\nuse the full path as parameter.") % { 'program': program }) else: aaui.UI_Info(_("%s does not exist, please double-check the path.") % program) sys.exit(1) def cmd_disable(self): apparmor.read_profiles() for (program, profile) in self.get_next_to_profile(): output_name = profile if program is None else program if not os.path.isfile(profile) or apparmor.is_skippable_file(profile): aaui.UI_Info(_('Profile for %s not found, skipping') % output_name) continue aaui.UI_Info(_('Disabling %s.') % output_name) self.disable_profile(profile) self.unload_profile(profile) def cmd_enforce(self): apparmor.read_profiles() for (program, profile) in self.get_next_to_profile(): output_name = profile if program is None else program if not os.path.isfile(profile) or apparmor.is_skippable_file(profile): aaui.UI_Info(_('Profile for %s not found, skipping') % output_name) continue apparmor.set_enforce(profile, program) self.reload_profile(profile) def cmd_complain(self): apparmor.read_profiles() for (program, profile) in self.get_next_to_profile(): output_name = profile if program is None else program if not os.path.isfile(profile) or apparmor.is_skippable_file(profile): aaui.UI_Info(_('Profile for %s not found, skipping') % output_name) continue apparmor.set_complain(profile, program) self.reload_profile(profile) def cmd_audit(self): apparmor.read_profiles() for (program, profile) in self.get_next_to_profile(): output_name = profile if program is None else program if not os.path.isfile(profile) or apparmor.is_skippable_file(profile): aaui.UI_Info(_('Profile for %s not found, skipping') % output_name) continue # keep this to allow toggling 'audit' flags if not self.remove: aaui.UI_Info(_('Setting %s to audit mode.') % output_name) else: aaui.UI_Info(_('Removing audit mode from %s.') % output_name) apparmor.change_profile_flags(profile, program, 'audit', not self.remove) disable_link = '%s/disable/%s' % (apparmor.profile_dir, os.path.basename(profile)) if os.path.exists(disable_link): aaui.UI_Info(_('\nWarning: the profile %s is disabled. Use aa-enforce or aa-complain to enable it.') % os.path.basename(profile)) self.reload_profile(profile) def cmd_autodep(self): apparmor.read_profiles() for (program, profile) in self.get_next_to_profile(): if not program: aaui.UI_Info(_('Please pass an application to generate a profile for, not a profile itself - skipping %s.') % profile) continue apparmor.check_qualifiers(program) if os.path.exists(apparmor.get_profile_filename_from_attachment(program, True)) and not self.force: aaui.UI_Info(_('Profile for %s already exists - skipping.') % program) else: apparmor.autodep(program) if self.aa_mountpoint: apparmor.reload(program) def clean_profile(self, program): filename = apparmor.get_profile_filename_from_attachment(program, True) import apparmor.cleanprofile as cleanprofile prof = cleanprofile.Prof(filename) cleanprof = cleanprofile.CleanProf(True, prof, prof) deleted = cleanprof.remove_duplicate_rules(program) aaui.UI_Info(_("\nDeleted %s rules.") % deleted) apparmor.changed[program] = True if filename: if not self.silent: q = aaui.PromptQuestion() q.title = 'Changed Local Profiles' q.explanation = _('The local profile for %(program)s in file %(file)s was changed. Would you like to save it?') % { 'program': program, 'file': filename } q.functions = ['CMD_SAVE_CHANGES', 'CMD_VIEW_CHANGES', 'CMD_ABORT'] q.default = 'CMD_VIEW_CHANGES' q.options = [] q.selected = 0 ans = '' arg = None while ans != 'CMD_SAVE_CHANGES': ans, arg = q.promptUser() if ans == 'CMD_SAVE_CHANGES': apparmor.write_profile_ui_feedback(program, True) self.reload_profile(filename) elif ans == 'CMD_VIEW_CHANGES': #oldprofile = apparmor.serialize_profile(apparmor.original_aa[program], program, '') newprofile = apparmor.serialize_profile(apparmor.aa[program], program, {'is_attachment': True}) aaui.UI_Changes(filename, newprofile, comments=True) else: apparmor.write_profile_ui_feedback(program, True) self.reload_profile(filename) else: raise apparmor.AppArmorException(_('The profile for %s does not exists. Nothing to clean.') % program) def enable_profile(self, filename): apparmor.delete_symlink('disable', filename) def disable_profile(self, filename): apparmor.create_symlink('disable', filename) def unload_profile(self, profile): if not self.do_reload: return # FIXME: should ensure profile is loaded before unloading cmd_info = cmd([apparmor.parser, '-I%s' % apparmor.profile_dir, '--base', apparmor.profile_dir, '-R', profile]) if cmd_info[0] != 0: raise apparmor.AppArmorException(cmd_info[1]) def reload_profile(self, profile): if not self.do_reload: return cmd_info = cmd([apparmor.parser, '-I%s' % apparmor.profile_dir, '--base', apparmor.profile_dir, '-r', profile]) if cmd_info[0] != 0: raise apparmor.AppArmorException(cmd_info[1]) apparmor-2.13.3/utils/apparmor/regex.py0000644000175000017500000002157013502024172015657 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2014-2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import re from apparmor.common import AppArmorBug, AppArmorException # setup module translations from apparmor.translations import init_translation _ = init_translation() ## Profile parsing Regex RE_AUDIT_DENY = '^\s*(?Paudit\s+)?(?Pallow\s+|deny\s+)?' # line start, optionally: leading whitespace, and /deny RE_EOL = '\s*(?P#.*?)?\s*$' # optional whitespace, optional , optional whitespace, end of the line RE_COMMA_EOL = '\s*,' + RE_EOL # optional whitespace, comma + RE_EOL RE_PROFILE_NAME = '(?P<%s>(\S+|"[^"]+"))' # string without spaces, or quoted string. %s is the match group name RE_PATH = '/\S*|"/[^"]*"' # filename (starting with '/') without spaces, or quoted filename. RE_PROFILE_PATH = '(?P<%s>(' + RE_PATH + '))' # quoted or unquoted filename. %s is the match group name RE_PROFILE_PATH_OR_VAR = '(?P<%s>(' + RE_PATH + '|@{\S+}\S*|"@{\S+}[^"]*"))' # quoted or unquoted filename or variable. %s is the match group name RE_SAFE_OR_UNSAFE = '(?P(safe|unsafe))' RE_PROFILE_END = re.compile('^\s*\}' + RE_EOL) RE_PROFILE_CAP = re.compile(RE_AUDIT_DENY + 'capability(?P(\s+\S+)+)?' + RE_COMMA_EOL) RE_PROFILE_LINK = re.compile(RE_AUDIT_DENY + 'link\s+(((subset)|(<=))\s+)?([\"\@\/].*?"??)\s+->\s*([\"\@\/].*?"??)' + RE_COMMA_EOL) RE_PROFILE_ALIAS = re.compile('^\s*alias\s+("??.+?"??)\s+->\s*("??.+?"??)' + RE_COMMA_EOL) RE_PROFILE_RLIMIT = re.compile('^\s*set\s+rlimit\s+(?P[a-z]+)\s*<=\s*(?P[^ ]+(\s+[a-zA-Z]+)?)' + RE_COMMA_EOL) RE_PROFILE_BOOLEAN = re.compile('^\s*(\$\{?\w*\}?)\s*=\s*(true|false)\s*,?' + RE_EOL, flags=re.IGNORECASE) RE_PROFILE_VARIABLE = re.compile('^\s*(@\{?\w+\}?)\s*(\+?=)\s*(@*.+?)\s*,?' + RE_EOL) RE_PROFILE_CONDITIONAL = re.compile('^\s*if\s+(not\s+)?(\$\{?\w*\}?)\s*\{' + RE_EOL) RE_PROFILE_CONDITIONAL_VARIABLE = re.compile('^\s*if\s+(not\s+)?defined\s+(@\{?\w+\}?)\s*\{\s*(#.*)?$') RE_PROFILE_CONDITIONAL_BOOLEAN = re.compile('^\s*if\s+(not\s+)?defined\s+(\$\{?\w+\}?)\s*\{\s*(#.*)?$') RE_PROFILE_NETWORK = re.compile(RE_AUDIT_DENY + 'network(?P
\s+.*)?' + RE_COMMA_EOL) RE_PROFILE_CHANGE_HAT = re.compile('^\s*\^(\"??.+?\"??)' + RE_COMMA_EOL) RE_PROFILE_HAT_DEF = re.compile('^(?P\s*)(?P\^|hat\s+)(?P\"??.+?\"??)\s+((flags=)?\((?P.+)\)\s+)*\{' + RE_EOL) RE_PROFILE_DBUS = re.compile(RE_AUDIT_DENY + '(dbus\s*,|dbus(?P
\s+[^#]*)\s*,)' + RE_EOL) RE_PROFILE_MOUNT = re.compile(RE_AUDIT_DENY + '((mount|remount|umount|unmount)(\s+[^#]*)?\s*,)' + RE_EOL) RE_PROFILE_SIGNAL = re.compile(RE_AUDIT_DENY + '(signal\s*,|signal(?P
\s+[^#]*)\s*,)' + RE_EOL) RE_PROFILE_PTRACE = re.compile(RE_AUDIT_DENY + '(ptrace\s*,|ptrace(?P
\s+[^#]*)\s*,)' + RE_EOL) RE_PROFILE_PIVOT_ROOT = re.compile(RE_AUDIT_DENY + '(pivot_root\s*,|pivot_root\s+[^#]*\s*,)' + RE_EOL) RE_PROFILE_UNIX = re.compile(RE_AUDIT_DENY + '(unix\s*,|unix\s+[^#]*\s*,)' + RE_EOL) # match anything that's not " or #, or matching quotes with anything except quotes inside __re_no_or_quoted_hash = '([^#"]|"[^"]*")*' RE_RULE_HAS_COMMA = re.compile('^' + __re_no_or_quoted_hash + ',\s*(#.*)?$') # match comma plus any trailing comment RE_HAS_COMMENT_SPLIT = re.compile('^(?P' + __re_no_or_quoted_hash + ')' + # store in 'not_comment' group '(?P#.*)$') # match trailing comment and store in 'comment' group RE_PROFILE_START = re.compile( '^(?P\s*)' + '(' + RE_PROFILE_PATH_OR_VAR % 'plainprofile' + # just a path '|' + # or '(' + 'profile' + '\s+' + RE_PROFILE_NAME % 'namedprofile' + '(\s+' + RE_PROFILE_PATH_OR_VAR % 'attachment' + ')?' + ')' + # 'profile', profile name, optionally attachment ')' + '\s+((flags\s*=\s*)?\((?P.+)\)\s*)?\{' + RE_EOL) RE_PROFILE_CHANGE_PROFILE = re.compile( RE_AUDIT_DENY + 'change_profile' + '(\s+' + RE_SAFE_OR_UNSAFE + ')?' + # optionally exec mode '(\s+' + RE_PROFILE_PATH_OR_VAR % 'execcond' + ')?' + # optionally exec condition '(\s+->\s*' + RE_PROFILE_NAME % 'targetprofile' + ')?' + # optionally '->' target profile RE_COMMA_EOL) # RE_PATH_PERMS is as restrictive as possible, but might still cause mismatches when adding different rule types. # Therefore parsing code should match against file rules only after trying to match all other rule types. RE_PATH_PERMS = '(?P<%s>[mrwalkPUCpucix]+)' RE_PROFILE_FILE_ENTRY = re.compile( RE_AUDIT_DENY + '(?Powner\s+)?' + # optionally: '(' + '(?Pfile)' + # bare 'file,' '|' + # or '(?Pfile\s+)?' + # optional 'file' keyword '(' + RE_PROFILE_PATH_OR_VAR % 'path' + '\s+' + RE_PATH_PERMS % 'perms' + # path and perms '|' + # or RE_PATH_PERMS % 'perms2' + '\s+' + RE_PROFILE_PATH_OR_VAR % 'path2' + # perms and path ')' + '(\s+->\s*' + RE_PROFILE_NAME % 'target' + ')?' + ')' + RE_COMMA_EOL) def parse_profile_start_line(line, filename): matches = RE_PROFILE_START.search(line) if not matches: raise AppArmorBug('The given line from file %(filename)s is not the start of a profile: %(line)s' % { 'filename': filename, 'line': line } ) result = {} for section in [ 'leadingspace', 'plainprofile', 'namedprofile', 'attachment', 'flags', 'comment']: if matches.group(section): result[section] = matches.group(section) # sections with optional quotes if section in ['plainprofile', 'namedprofile', 'attachment']: result[section] = strip_quotes(result[section]) else: result[section] = None if result['flags'] and result['flags'].strip() == '': raise AppArmorException(_('Invalid syntax in %(filename)s: Empty set of flags in line %(line)s.' % { 'filename': filename, 'line': line } )) if result['plainprofile']: result['profile'] = result['plainprofile'] result['profile_keyword'] = False else: result['profile'] = result['namedprofile'] result['profile_keyword'] = True return result RE_ABI = re.compile('^\s*#?abi\s*(<(?P.*)>|"(?P.*)"|(?P[^<>"]*))' + RE_COMMA_EOL) RE_INCLUDE = re.compile('^\s*#?include\s*(<(?P.*)>|"(?P.*)"|(?P[^<>"]*))' + RE_EOL) def re_match_include(line): """Matches the path for include and returns the include path""" matches = RE_INCLUDE.search(line) if not matches: return None path = None if matches.group('magicpath'): path = matches.group('magicpath').strip() elif matches.group('unquotedpath'): # LP: #1738879 - parser doesn't handle unquoted paths everywhere # path = matches.group('unquotedpath').strip() raise AppArmorException(_('Syntax error: #include must use quoted path or <...>')) elif matches.group('quotedpath'): path = matches.group('quotedpath') # LP: 1738880 - parser doesn't handle relative paths everywhere, and # neither do we (see aa.py) if len(path) > 0 and path[0] != '/': raise AppArmorException(_('Syntax error: #include must use quoted path or <...>')) # if path is empty or the empty string if path is None or path == "": raise AppArmorException(_('Syntax error: #include rule with empty filename')) # LP: #1738877 - parser doesn't handle files with spaces in the name if re.search('\s', path): raise AppArmorException(_('Syntax error: #include rule filename cannot contain spaces')) return path def strip_parenthesis(data): '''strips parenthesis from the given string and returns the strip()ped result. The parenthesis must be the first and last char, otherwise they won't be removed. Even if no parenthesis get removed, the result will be strip()ped. ''' if data[0] + data[-1] == '()': return data[1:-1].strip() else: return data.strip() def strip_quotes(data): if data[0] + data[-1] == '""': return data[1:-1] else: return data apparmor-2.13.3/utils/apparmor/severity.py0000644000175000017500000002557313502024172016426 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- from __future__ import with_statement import os import re from apparmor.common import AppArmorException, open_file_read, warn, convert_regexp # , msg, error, debug from apparmor.regex import re_match_include class Severity(object): def __init__(self, dbname=None, default_rank=10): """Initialises the class object""" self.PROF_DIR = '/etc/apparmor.d' # The profile directory self.NOT_IMPLEMENTED = '_-*not*implemented*-_' # used for rule types that don't have severity ratings self.severity = dict() self.severity['DATABASENAME'] = dbname self.severity['CAPABILITIES'] = {} self.severity['FILES'] = {} self.severity['REGEXPS'] = {} self.severity['DEFAULT_RANK'] = default_rank # For variable expansions for the profile self.severity['VARIABLES'] = dict() if not dbname: raise AppArmorException("No severity db file given") with open_file_read(dbname) as database: # open(dbname, 'r') for lineno, line in enumerate(database, start=1): line = line.strip() # or only rstrip and lstrip? if line == '' or line.startswith('#'): continue if line.startswith('/'): try: path, read, write, execute = line.split() read, write, execute = int(read), int(write), int(execute) except ValueError: raise AppArmorException("Insufficient values for permissions in file: %s\n\t[Line %s]: %s" % (dbname, lineno, line)) else: if read not in range(0, 11) or write not in range(0, 11) or execute not in range(0, 11): raise AppArmorException("Inappropriate values for permissions in file: %s\n\t[Line %s]: %s" % (dbname, lineno, line)) path = path.lstrip('/') if '*' not in path: self.severity['FILES'][path] = {'r': read, 'w': write, 'x': execute} else: ptr = self.severity['REGEXPS'] pieces = path.split('/') for index, piece in enumerate(pieces): if '*' in piece: path = '/'.join(pieces[index:]) regexp = convert_regexp(path) ptr[regexp] = {'AA_RANK': {'r': read, 'w': write, 'x': execute}} break else: ptr[piece] = ptr.get(piece, {}) ptr = ptr[piece] elif line.startswith('CAP_'): try: resource, severity = line.split() severity = int(severity) except ValueError: error_message = 'No severity value present in file: %s\n\t[Line %s]: %s' % (dbname, lineno, line) #error(error_message) raise AppArmorException(error_message) # from None else: if severity not in range(0, 11): raise AppArmorException("Inappropriate severity value present in file: %s\n\t[Line %s]: %s" % (dbname, lineno, line)) self.severity['CAPABILITIES'][resource] = severity else: raise AppArmorException("Unexpected line in file: %s\n\t[Line %s]: %s" % (dbname, lineno, line)) def rank_capability(self, resource): """Returns the severity of for the capability resource, default value if no match""" cap = 'CAP_%s' % resource.upper() if resource == '__ALL__': return max(self.severity['CAPABILITIES'].values()) if cap in self.severity['CAPABILITIES'].keys(): return self.severity['CAPABILITIES'][cap] # raise ValueError("unexpected capability rank input: %s"%resource) warn("unknown capability: %s" % resource) return self.severity['DEFAULT_RANK'] def rank_path(self, path, mode=None): """Returns the rank for the given path""" if '@' in path: # path contains variable return self.handle_variable_rank(path, mode) elif path[0] == '/': # file resource return self.handle_file(path, mode) else: raise AppArmorException("Unexpected path input: %s" % path) def check_subtree(self, tree, mode, sev, segments): """Returns the max severity from the regex tree""" if len(segments) == 0: first = '' else: first = segments[0] rest = segments[1:] path = '/'.join([first] + rest) # Check if we have a matching directory tree to descend into if tree.get(first, False): sev = self.check_subtree(tree[first], mode, sev, rest) # If severity still not found, match against globs if sev is None: # Match against all globs at this directory level for chunk in tree.keys(): if '*' in chunk: # Match rest of the path if re.search("^" + chunk, path): # Find max rank if "AA_RANK" in tree[chunk].keys(): for m in mode: if sev is None or tree[chunk]["AA_RANK"].get(m, -1) > sev: sev = tree[chunk]["AA_RANK"].get(m, None) return sev def handle_file(self, resource, mode): """Returns the severity for the file, default value if no match found""" resource = resource[1:] # remove initial / from path pieces = resource.split('/') # break path into directory level chunks sev = None # Check for an exact match in the db if resource in self.severity['FILES'].keys(): # Find max value among the given modes for m in mode: if sev is None or self.severity['FILES'][resource].get(m, -1) > sev: sev = self.severity['FILES'][resource].get(m, None) else: # Search regex tree for matching glob sev = self.check_subtree(self.severity['REGEXPS'], mode, sev, pieces) if sev is None: # Return default rank if severity cannot be found return self.severity['DEFAULT_RANK'] else: return sev def handle_variable_rank(self, resource, mode): """Returns the max possible rank for file resources containing variables""" regex_variable = re.compile('@{([^{.]*)}') matches = regex_variable.search(resource) if matches: rank = self.severity['DEFAULT_RANK'] variable = '@{%s}' % matches.groups()[0] #variables = regex_variable.findall(resource) for replacement in self.severity['VARIABLES'][variable]: resource_replaced = self.variable_replace(variable, replacement, resource) rank_new = self.handle_variable_rank(resource_replaced, mode) if rank == self.severity['DEFAULT_RANK']: rank = rank_new elif rank_new != self.severity['DEFAULT_RANK'] and rank_new > rank: rank = rank_new return rank else: return self.handle_file(resource, mode) def variable_replace(self, variable, replacement, resource): """Returns the expanded path for the passed variable""" leading = False trailing = False # Check for leading or trailing / that may need to be collapsed if resource.find("/" + variable) != -1 and resource.find("//" + variable) == -1: # find that a single / exists before variable or not leading = True if resource.find(variable + "/") != -1 and resource.find(variable + "//") == -1: trailing = True if replacement[0] == '/' and replacement[:2] != '//' and leading: # finds if the replacement has leading / or not replacement = replacement[1:] if replacement[-1] == '/' and replacement[-2:] != '//' and trailing: replacement = replacement[:-1] return resource.replace(variable, replacement) def load_variables(self, prof_path): """Loads the variables for the given profile""" if os.path.isfile(prof_path): with open_file_read(prof_path) as f_in: for line in f_in: line = line.strip() # If any includes, load variables from them first match = re_match_include(line) if match: new_path = match if not new_path.startswith('/'): new_path = self.PROF_DIR + '/' + match self.load_variables(new_path) else: # Remove any comments if '#' in line: line = line.split('#')[0].rstrip() # Expected format is @{Variable} = value1 value2 .. if line.startswith('@') and '=' in line: if '+=' in line: line = line.split('+=') try: self.severity['VARIABLES'][line[0]] += [i.strip('"') for i in line[1].split()] except KeyError: raise AppArmorException("Variable %s was not previously declared, but is being assigned additional value in file: %s" % (line[0], prof_path)) else: line = line.split('=') if line[0] in self.severity['VARIABLES'].keys(): raise AppArmorException("Variable %s was previously declared in file: %s" % (line[0], prof_path)) self.severity['VARIABLES'][line[0]] = [i.strip('"') for i in line[1].split()] def unload_variables(self): """Clears all loaded variables""" self.severity['VARIABLES'] = dict() apparmor-2.13.3/utils/apparmor/aare.py0000644000175000017500000001511413502024172015452 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import re from apparmor.common import convert_regexp, type_is_str, AppArmorBug, AppArmorException class AARE(object): '''AARE (AppArmor Regular Expression) wrapper class''' def __init__(self, regex, is_path, log_event=None): '''create an AARE instance for the given AppArmor regex If is_path is true, the regex is expected to be a path and therefore must start with / or a variable.''' # using the specified variables when matching. if is_path: if regex.startswith('/'): pass elif regex.startswith('@{'): pass # XXX ideally check variable content - each part must start with / - or another variable, which must start with / else: raise AppArmorException("Path doesn't start with / or variable: %s" % regex) if log_event: self.orig_regex = regex self.regex = convert_expression_to_aare(regex) else: self.orig_regex = None self.regex = regex self._regex_compiled = None # done on first use in match() - that saves us some re.compile() calls # self.variables = variables # XXX def __repr__(self): '''returns a "printable" representation of AARE''' return "AARE('%s')" % self.regex def __deepcopy__(self, memo): # thanks to http://bugs.python.org/issue10076, we need to implement this ourself if self.orig_regex: return AARE(self.orig_regex, is_path=False, log_event=True) else: return AARE(self.regex, is_path=False) # check if a regex is a plain path (not containing variables, alternations or wildcards) # some special characters are probably not covered by the plain_path regex (if in doubt, better error out on the safe side) plain_path = re.compile('^[0-9a-zA-Z/._-]+$') def match(self, expression): '''check if the given expression (string or AARE) matches the regex''' if type(expression) == AARE: if expression.orig_regex: expression = expression.orig_regex elif self.plain_path.match(expression.regex): # regex doesn't contain variables or wildcards, therefore handle it as plain path expression = expression.regex else: return self.is_equal(expression) # better safe than sorry elif not type_is_str(expression): raise AppArmorBug('AARE.match() called with unknown object: %s' % str(expression)) if self._regex_compiled is None: self._regex_compiled = re.compile(convert_regexp(self.regex)) return bool(self._regex_compiled.match(expression)) def is_equal(self, expression): '''check if the given expression is equal''' if type(expression) == AARE: return self.regex == expression.regex elif type_is_str(expression): return self.regex == expression else: raise AppArmorBug('AARE.is_equal() called with unknown object: %s' % str(expression)) def glob_path(self): '''Glob the given file or directory path''' if self.regex[-1] == '/': if self.regex[-4:] == '/**/' or self.regex[-3:] == '/*/': # /foo/**/ and /foo/*/ => /**/ newpath = re.sub('/[^/]+/\*{1,2}/$', '/**/', self.regex) # re.sub('/[^/]+/\*{1,2}$/', '/\*\*/', self.regex) elif re.search('/[^/]+\*\*[^/]*/$', self.regex): # /foo**/ and /foo**bar/ => /**/ newpath = re.sub('/[^/]+\*\*[^/]*/$', '/**/', self.regex) elif re.search('/\*\*[^/]+/$', self.regex): # /**bar/ => /**/ newpath = re.sub('/\*\*[^/]+/$', '/**/', self.regex) else: newpath = re.sub('/[^/]+/$', '/*/', self.regex) else: if self.regex[-3:] == '/**' or self.regex[-2:] == '/*': # /foo/** and /foo/* => /** newpath = re.sub('/[^/]+/\*{1,2}$', '/**', self.regex) elif re.search('/[^/]*\*\*[^/]+$', self.regex): # /**foo and /foor**bar => /** newpath = re.sub('/[^/]*\*\*[^/]+$', '/**', self.regex) elif re.search('/[^/]+\*\*$', self.regex): # /foo** => /** newpath = re.sub('/[^/]+\*\*$', '/**', self.regex) else: newpath = re.sub('/[^/]+$', '/*', self.regex) return AARE(newpath, False) def glob_path_withext(self): '''Glob given file path with extension Files without extensions and directories won't be changed''' # match /**.ext and /*.ext match = re.search('/\*{1,2}(\.[^/]+)$', self.regex) if match: # /foo/**.ext and /foo/*.ext => /**.ext newpath = re.sub('/[^/]+/\*{1,2}\.[^/]+$', '/**' + match.groups()[0], self.regex) elif re.search('/[^/]+\*\*[^/]*\.[^/]+$', self.regex): # /foo**.ext and /foo**bar.ext => /**.ext match = re.search('/[^/]+\*\*[^/]*(\.[^/]+)$', self.regex) newpath = re.sub('/[^/]+\*\*[^/]*\.[^/]+$', '/**' + match.groups()[0], self.regex) elif re.search('/\*\*[^/]+\.[^/]+$', self.regex): # /**foo.ext => /**.ext match = re.search('/\*\*[^/]+(\.[^/]+)$', self.regex) newpath = re.sub('/\*\*[^/]+\.[^/]+$', '/**' + match.groups()[0], self.regex) else: newpath = self.regex match = re.search('(\.[^/]+)$', self.regex) if match: newpath = re.sub('/[^/]+(\.[^/]+)$', '/*' + match.groups()[0], self.regex) return AARE(newpath, False) def convert_expression_to_aare(expression): '''convert an expression (taken from audit.log) to an AARE string''' aare_escape_chars = ['\\', '?', '*', '[', ']', '{', '}', '"', '!'] for char in aare_escape_chars: expression = expression.replace(char, '\\' + char) return expression apparmor-2.13.3/utils/apparmor/common.py0000644000175000017500000002242113502024172016031 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2012 Canonical Ltd. # Copyright (C) 2013 Kshitij Gupta # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ from __future__ import print_function import codecs import collections import glob import logging import os import re import subprocess import sys import termios import tty import apparmor.rules as rules DEBUGGING = False # # Utility classes # class AppArmorException(Exception): '''This class represents AppArmor exceptions''' def __init__(self, value): self.value = value def __str__(self): return repr(self.value) class AppArmorBug(Exception): '''This class represents AppArmor exceptions "that should never happen"''' pass # # Utility functions # def error(out, exit_code=1, do_exit=True): '''Print error message and exit''' try: print("ERROR: %s" % (out), file=sys.stderr) except IOError: pass if do_exit: sys.exit(exit_code) def warn(out): '''Print warning message''' try: print("WARN: %s" % (out), file=sys.stderr) except IOError: pass def msg(out, output=sys.stdout): '''Print message''' try: print("%s" % (out), file=output) except IOError: pass def debug(out): '''Print debug message''' global DEBUGGING if DEBUGGING: try: print("DEBUG: %s" % (out), file=sys.stderr) except IOError: pass def recursive_print(src, dpth = 0, key = ''): # print recursively in a nicely formatted way # useful for debugging, too verbose for production code ;-) # based on code "stolen" from Scott S-Allen / MIT License # http://code.activestate.com/recipes/578094-recursively-print-nested-dictionaries/ """ Recursively prints nested elements.""" tabs = ' ' * dpth * 4 # or 2 or 8 or... if isinstance(src, dict): empty = True for key in src.keys(): print (tabs + '[%s]' % key) recursive_print(src[key], dpth + 1, key) empty = False if empty: print (tabs + '[--- empty ---]') elif isinstance(src, list) or isinstance(src, tuple): if len(src) == 0: print (tabs + '[--- empty ---]') else: print (tabs + "[") for litem in src: recursive_print(litem, dpth + 1) print (tabs + "]") elif isinstance(src, rules._Raw_Rule): src.recursive_print(dpth) else: if key: print (tabs + '%s = %s' % (key, src)) else: print (tabs + '- %s' % src) def cmd(command): '''Try to execute the given command.''' debug(command) try: sp = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except OSError as ex: return [127, str(ex)] if sys.version_info[0] >= 3: out = sp.communicate()[0].decode('ascii', 'ignore') else: out = sp.communicate()[0] return [sp.returncode, out] def cmd_pipe(command1, command2): '''Try to pipe command1 into command2.''' try: sp1 = subprocess.Popen(command1, stdout=subprocess.PIPE) sp2 = subprocess.Popen(command2, stdin=sp1.stdout) except OSError as ex: return [127, str(ex)] if sys.version_info[0] >= 3: out = sp2.communicate()[0].decode('ascii', 'ignore') else: out = sp2.communicate()[0] return [sp2.returncode, out] def valid_path(path): '''Valid path''' # No relative paths m = "Invalid path: %s" % (path) if not path.startswith('/'): debug("%s (relative)" % (m)) return False if '"' in path: # We double quote elsewhere debug("%s (contains quote)" % (m)) return False try: os.path.normpath(path) except Exception: debug("%s (could not normalize)" % (m)) return False return True def get_directory_contents(path): '''Find contents of the given directory''' if not valid_path(path): return None files = [] for f in glob.glob(path + "/*"): files.append(f) files.sort() return files def open_file_read(path, encoding='UTF-8'): '''Open specified file read-only''' return open_file_anymode('r', path, encoding) def open_file_write(path): '''Open specified file in write/overwrite mode''' return open_file_anymode('w', path, 'UTF-8') def open_file_anymode(mode, path, encoding='UTF-8'): '''Open specified file in specified mode''' errorhandling = 'surrogateescape' if sys.version_info[0] < 3: errorhandling = 'replace' orig = codecs.open(path, mode, encoding, errors=errorhandling) return orig def readkey(): '''Returns the pressed key''' fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: tty.setraw(sys.stdin.fileno()) ch = sys.stdin.read(1) finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) return ch def hasher(): '''A neat alternative to perl's hash reference''' # Creates a dictionary for any depth and returns empty dictionary otherwise # WARNING: when reading non-existing sub-dicts, empty dicts will be added. # This might cause strange effects when using .keys() return collections.defaultdict(hasher) def convert_regexp(regexp): regex_paren = re.compile('^(.*){([^}]*)}(.*)$') regexp = regexp.strip() new_reg = re.sub(r'(? 2: unicode = str # python 3 dropped the unicode type. To keep type_is_str() simple (and pyflakes3 happy), re-create it as alias of str. def type_is_str(var): ''' returns True if the given variable is a str (or unicode string when using python 2)''' if type(var) in [str, unicode]: # python 2 sometimes uses the 'unicode' type return True else: return False class DebugLogger(object): def __init__(self, module_name=__name__): self.debugging = False self.logfile = '/var/log/apparmor/logprof.log' self.debug_level = logging.DEBUG if os.getenv('LOGPROF_DEBUG', False): self.debugging = os.getenv('LOGPROF_DEBUG') try: self.debugging = int(self.debugging) except Exception: self.debugging = False if self.debugging not in range(0, 4): sys.stdout.write('Environment Variable: LOGPROF_DEBUG contains invalid value: %s' % os.getenv('LOGPROF_DEBUG')) if self.debugging == 0: # debugging disabled, don't need to setup logging return if self.debugging == 1: self.debug_level = logging.ERROR elif self.debugging == 2: self.debug_level = logging.INFO elif self.debugging == 3: self.debug_level = logging.DEBUG try: logging.basicConfig(filename=self.logfile, level=self.debug_level, format='%(asctime)s - %(name)s - %(message)s\n') except IOError: # Unable to open the default logfile, so create a temporary logfile and tell use about it import tempfile templog = tempfile.NamedTemporaryFile('w', prefix='apparmor', suffix='.log', delete=False) sys.stdout.write("\nCould not open: %s\nLogging to: %s\n" % (self.logfile, templog.name)) logging.basicConfig(filename=templog.name, level=self.debug_level, format='%(asctime)s - %(name)s - %(message)s\n') self.logger = logging.getLogger(module_name) def error(self, message): if self.debugging: self.logger.error(message) def info(self, message): if self.debugging: self.logger.info(message) def debug(self, message): if self.debugging: self.logger.debug(message) def shutdown(self): logging.shutdown() #logging.shutdown([self.logger]) apparmor-2.13.3/utils/apparmor/profile_list.py0000644000175000017500000000620713502024172017240 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2018 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- from apparmor.aare import AARE from apparmor.common import AppArmorBug, AppArmorException # setup module translations from apparmor.translations import init_translation _ = init_translation() class ProfileList: ''' Stores the list of profiles (both name and attachment) and in which files they live ''' def __init__(self): self.profile_names = {} # profile name -> filename self.attachments = {} # attachment -> filename self.attachments_AARE = {} # AARE(attachment) -> filename def add(self, filename, profile_name, attachment): ''' Add the given profile and attachment to the list ''' if not filename: raise AppArmorBug('Empty filename given to ProfileList') if not profile_name and not attachment: raise AppArmorBug('Neither profile name or attachment given') if profile_name in self.profile_names: raise AppArmorException(_('Profile %(profile_name)s exists in %(filename)s and %(filename2)s' % {'profile_name': profile_name, 'filename': filename, 'filename2': self.profile_names[profile_name]})) if attachment in self.attachments: raise AppArmorException(_('Profile for %(profile_name)s exists in %(filename)s and %(filename2)s' % {'profile_name': attachment, 'filename': filename, 'filename2': self.attachments[attachment]})) if profile_name: self.profile_names[profile_name] = filename if attachment: self.attachments[attachment] = filename self.attachments_AARE[attachment] = AARE(attachment, True) def filename_from_profile_name(self, name): ''' Return profile filename for the given profile name, or None ''' return self.profile_names.get(name, None) def filename_from_attachment(self, attachment): ''' Return profile filename for the given attachment/executable path, or None ''' if not attachment.startswith( ('/', '@', '{') ): raise AppArmorBug('Called filename_from_attachment with non-path attachment: %s' % attachment) # plain path if self.attachments.get(attachment): return self.attachments[attachment] # try AARE matches to cover profile names with alternations and wildcards for path in self.attachments.keys(): if self.attachments_AARE[path].match(attachment): return self.attachments[path] # XXX this returns the first match, not necessarily the best one return None # nothing found apparmor-2.13.3/utils/apparmor/fail.py0000644000175000017500000000440113502024172015452 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ from __future__ import print_function # needed in py2 for print('...', file=sys.stderr) import cgitb import os import sys import tempfile import traceback from apparmor.common import error # # Exception handling # def handle_exception(*exc_info): '''Used as exception handler in the aa-* tools. For AppArmorException (used for profile syntax errors etc.), print only the exceptions value because a backtrace is superfluous and would confuse users. For other exceptions, print backtrace and save detailed information in a file in /tmp/ (including variable content etc.) to make debugging easier. ''' (ex_cls, ex, tb) = exc_info if ex_cls.__name__ == 'AppArmorException': # I didn't find a way to get this working with isinstance() :-/ print('', file=sys.stderr) error(ex.value) else: (fd, path) = tempfile.mkstemp(prefix='apparmor-bugreport-', suffix='.txt') file = os.fdopen(fd, 'w') #file = open_file_write(path) # writes everything converted to utf8 - not sure if we want this... cgitb_hook = cgitb.Hook(display=1, file=file, format='text', context=10) cgitb_hook.handle(exc_info) file.write('Please consider reporting a bug at https://bugs.launchpad.net/apparmor/\n') file.write('and attach this file.\n') print(''.join(traceback.format_exception(*exc_info)), file=sys.stderr) print('', file=sys.stderr) print('An unexpected error occoured!', file=sys.stderr) print('', file=sys.stderr) print('For details, see %s' % path, file=sys.stderr) print('Please consider reporting a bug at https://bugs.launchpad.net/apparmor/', file=sys.stderr) print('and attach this file.', file=sys.stderr) def enable_aa_exception_handler(): '''Setup handle_exception() as exception handler''' sys.excepthook = handle_exception apparmor-2.13.3/utils/apparmor/translations.py0000644000175000017500000000126513502024172017265 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import gettext TRANSLATION_DOMAIN = 'apparmor-utils' __apparmor_gettext__ = None def init_translation(): global __apparmor_gettext__ if __apparmor_gettext__ is None: t = gettext.translation(TRANSLATION_DOMAIN, fallback=True) __apparmor_gettext__ = t.gettext return __apparmor_gettext__ apparmor-2.13.3/utils/apparmor/sandbox.py0000644000175000017500000006445013502024172016207 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2011-2013 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ from apparmor.common import AppArmorException, debug, error, msg, cmd import apparmor.easyprof import optparse import os import pwd import re import signal import socket import sys import tempfile import time def check_requirements(binary): '''Verify necessary software is installed''' exes = ['xset', # for detecting free X display 'aa-easyprof', # for templates 'aa-exec', # for changing profile 'sudo', # eventually get rid of this 'pkexec', # eventually get rid of this binary] for e in exes: debug("Searching for '%s'" % e) rc, report = cmd(['which', e]) if rc != 0: error("Could not find '%s'" % e, do_exit=False) return False return True def parse_args(args=None, parser=None): '''Parse arguments''' if parser == None: parser = optparse.OptionParser() parser.add_option('-X', '--with-x', dest='withx', default=False, help='Run in isolated X server', action='store_true') parser.add_option('--with-xserver', dest='xserver', default='xpra', help='Nested X server to use: xpra (default), xpra3d, xephyr') parser.add_option('--with-clipboard', dest='with_clipboard', default=False, help='Allow clipboard access', action='store_true') parser.add_option('--with-xauthority', dest='xauthority', default=None, help='Specify Xauthority file to use') parser.add_option('-d', '--debug', dest='debug', default=False, help='Show debug messages', action='store_true') parser.add_option('--with-xephyr-geometry', dest='xephyr_geometry', default=None, help='Geometry for Xephyr window') parser.add_option('--profile', dest='profile', default=None, help='Specify an existing profile (see aa-status)') (my_opt, my_args) = parser.parse_args() if my_opt.debug: apparmor.common.DEBUGGING = True valid_xservers = ['xpra', 'xpra3d', 'xephyr'] if my_opt.withx and my_opt.xserver.lower() not in valid_xservers: error("Invalid server '%s'. Use one of: %s" % (my_opt.xserver, \ ", ".join(valid_xservers))) if my_opt.withx: if my_opt.xephyr_geometry and my_opt.xserver.lower() != "xephyr": error("Invalid option --with-xephyr-geometry with '%s'" % my_opt.xserver) elif my_opt.with_clipboard and my_opt.xserver.lower() == "xephyr": error("Clipboard not supported with '%s'" % my_opt.xserver) if my_opt.template == "default": if my_opt.withx: my_opt.template = "sandbox-x" else: my_opt.template = "sandbox" return (my_opt, my_args) def gen_policy_name(binary): '''Generate a temporary policy based on the binary name''' return "sandbox-%s%s" % (pwd.getpwuid(os.geteuid())[0], re.sub(r'/', '_', binary)) def set_environ(env): keys = env.keys() keys.sort() for k in keys: msg("Using: %s=%s" % (k, env[k])) os.environ[k] = env[k] def aa_exec(command, opt, environ={}, verify_rules=[]): '''Execute binary under specified policy''' if opt.profile != None: policy_name = opt.profile else: opt.ensure_value("template_var", None) opt.ensure_value("name", None) opt.ensure_value("comment", None) opt.ensure_value("author", None) opt.ensure_value("copyright", None) binary = command[0] policy_name = gen_policy_name(binary) easyp = apparmor.easyprof.AppArmorEasyProfile(binary, opt) params = apparmor.easyprof.gen_policy_params(policy_name, opt) policy = easyp.gen_policy(**params) debug("\n%s" % policy) tmp = tempfile.NamedTemporaryFile(prefix = '%s-' % policy_name) if sys.version_info[0] >= 3: tmp.write(bytes(policy, 'utf-8')) else: tmp.write(policy) tmp.flush() debug("using '%s' template" % opt.template) # TODO: get rid of this if opt.withx: rc, report = cmd(['pkexec', 'apparmor_parser', '-r', '%s' % tmp.name]) else: rc, report = cmd(['sudo', 'apparmor_parser', '-r', tmp.name]) if rc != 0: raise AppArmorException("Could not load policy") rc, report = cmd(['sudo', 'apparmor_parser', '-p', tmp.name]) if rc != 0: raise AppArmorException("Could not dump policy") # Make sure the dynamic profile has the appropriate line for X for r in verify_rules: found = False for line in report.splitlines(): line = line.strip() if r == line: found = True break if not found: raise AppArmorException("Could not find required rule: %s" % r) set_environ(environ) args = ['aa-exec', '-p', policy_name, '--'] + command rc, report = cmd(args) return rc, report def run_sandbox(command, opt): '''Run application''' # aa-exec rc, report = aa_exec(command, opt) return rc, report class SandboxXserver(): def __init__(self, title, geometry=None, driver=None, xauth=None, clipboard=False): self.geometry = geometry self.title = title self.pids = [] self.driver = driver self.clipboard = clipboard self.tempfiles = [] self.timeout = 5 # used by xauth and for server starts # preserve our environment self.old_environ = dict() for env in ['DISPLAY', 'XAUTHORITY', 'UBUNTU_MENUPROXY', 'QT_X11_NO_NATIVE_MENUBAR', 'LIBOVERLAY_SCROLLBAR']: if env in os.environ: self.old_environ[env] = os.environ[env] # prepare the new environment self.display, self.xauth = self.find_free_x_display() if xauth: abs_xauth = os.path.expanduser(xauth) if os.path.expanduser("~/.Xauthority") == abs_xauth: raise AppArmorException("Trusted Xauthority file specified. Aborting") self.xauth = abs_xauth self.new_environ = dict() self.new_environ['DISPLAY'] = self.display self.new_environ['XAUTHORITY'] = self.xauth # Disable the global menu for now self.new_environ["UBUNTU_MENUPROXY"] = "" self.new_environ["QT_X11_NO_NATIVE_MENUBAR"] = "1" # Disable the overlay scrollbar for now-- they don't track correctly self.new_environ["LIBOVERLAY_SCROLLBAR"] = "0" def cleanup(self): '''Cleanup our forked pids, reset the environment, etc''' self.pids.reverse() debug(self.pids) for pid in self.pids: # Kill server with TERM debug("kill %d" % pid) os.kill(pid, signal.SIGTERM) for pid in self.pids: # Shoot the server dead debug("kill -9 %d" % pid) os.kill(pid, signal.SIGKILL) for t in self.tempfiles: if os.path.exists(t): os.unlink(t) if os.path.exists(self.xauth): os.unlink(self.xauth) # Reset our environment set_environ(self.old_environ) def find_free_x_display(self): '''Find a free X display''' old_lang = None if 'LANG' in os.environ: old_lang = os.environ['LANG'] os.environ['LANG'] = 'C' display = "" current = self.old_environ["DISPLAY"] for i in range(1,257): # TODO: this puts an artificial limit of 256 # sandboxed applications tmp = ":%d" % i os.environ["DISPLAY"] = tmp rc, report = cmd(['xset', '-q']) if rc != 0 and 'Invalid MIT-MAGIC-COOKIE-1' not in report: display = tmp break if old_lang: os.environ['LANG'] = old_lang os.environ["DISPLAY"] = current if display == "": raise AppArmorException("Could not find available X display") # Use dedicated .Xauthority file xauth = os.path.join(os.path.expanduser('~'), \ '.Xauthority-sandbox%s' % display.split(':')[1]) return display, xauth def generate_title(self): return "(Sandbox%s) %s" % (self.display, self.title) def verify_host_setup(self): '''Make sure we have everything we need''' old_lang = None if 'LANG' in os.environ: old_lang = os.environ['LANG'] os.environ['LANG'] = 'C' rc, report = cmd(['xhost']) if old_lang: os.environ['LANG'] = old_lang if rc != 0: raise AppArmorException("'xhost' exited with error") if 'access control enabled' not in report: raise AppArmorException("Access control currently disabled. Please enable with 'xhost -'") username = pwd.getpwuid(os.geteuid())[0] if ':localuser:%s' % username in report: raise AppArmorException("Access control allows '%s' full access. Please see 'man aa-sandbox' for details" % username) def start(self): '''Start a nested X server (need to override)''' # clean up the old one if os.path.exists(self.xauth): os.unlink(self.xauth) rc, cookie = cmd(['mcookie']) if rc != 0: raise AppArmorException("Could not generate magic cookie") rc, out = cmd(['xauth', '-f', self.xauth, \ 'add', \ self.display, \ 'MIT-MAGIC-COOKIE-1', \ cookie.strip()]) if rc != 0: raise AppArmorException("Could not generate '%s'" % self.display) class SandboxXephyr(SandboxXserver): def start(self): for e in ['Xephyr', 'matchbox-window-manager']: debug("Searching for '%s'" % e) rc, report = cmd(['which', e]) if rc != 0: raise AppArmorException("Could not find '%s'" % e) '''Run any setup code''' SandboxXserver.start(self) '''Start a Xephyr server''' listener_x = os.fork() if listener_x == 0: # TODO: break into config file? Which are needed? x_exts = ['-extension', 'GLX', '-extension', 'MIT-SHM', '-extension', 'RENDER', '-extension', 'SECURITY', '-extension', 'DAMAGE' ] # verify_these x_extra_args = ['-host-cursor', # less secure? '-fakexa', # for games? seems not needed '-nodri', # more secure? ] if not self.geometry: self.geometry = "640x480" x_args = ['-nolisten', 'tcp', '-screen', self.geometry, '-br', # black background '-reset', # reset after last client exists '-terminate', # terminate at server reset '-title', self.generate_title(), ] + x_exts + x_extra_args args = ['/usr/bin/Xephyr'] + x_args + [self.display] debug(" ".join(args)) os.execv(args[0], args) sys.exit(0) self.pids.append(listener_x) time.sleep(1) # FIXME: detect if running # Next, start the window manager sys.stdout.flush() os.chdir(os.environ["HOME"]) listener_wm = os.fork() if listener_wm == 0: # update environment set_environ(self.new_environ) args = ['/usr/bin/matchbox-window-manager', '-use_titlebar', 'no'] debug(" ".join(args)) cmd(args) sys.exit(0) self.pids.append(listener_wm) time.sleep(1) # FIXME: detect if running class SandboxXpra(SandboxXserver): def cleanup(self): sys.stderr.flush() listener = os.fork() if listener == 0: args = ['/usr/bin/xpra', 'stop', self.display] debug(" ".join(args)) os.execv(args[0], args) sys.exit(0) time.sleep(2) # Annoyingly, xpra doesn't clean up itself well if the application # failed for some reason. Try to account for that. rc, report = cmd(['ps', 'auxww']) for line in report.splitlines(): if '-for-Xpra-%s' % self.display in line: self.pids.append(int(line.split()[1])) SandboxXserver.cleanup(self) def _get_xvfb_args(self): '''Setup xvfb arguments''' # Debugging tip (can also use glxinfo): # $ xdpyinfo > /tmp/native # $ aa-sandbox -X -t sandbox-x /usr/bin/xdpyinfo > /tmp/nested # $ diff -Naur /tmp/native /tmp/nested xvfb_args = [] if self.driver == None: # The default from the man page, but be explicit in what we enable xvfb_args.append('--xvfb=Xvfb') xvfb_args.append('-screen 0 3840x2560x24+32') xvfb_args.append('-nolisten tcp') xvfb_args.append('-noreset') xvfb_args.append('-auth %s' % self.new_environ['XAUTHORITY']) xvfb_args.append('+extension Composite') xvfb_args.append('+extension SECURITY') xvfb_args.append('-extension GLX') elif self.driver == 'xdummy': # The dummy driver allows us to use GLX, etc. See: # http://xpra.org/Xdummy.html conf = '''# /usr/share/doc/xpra/examples/dummy.xorg.conf.gz # http://xpra.org/Xdummy.html ##Xdummy:## Section "ServerFlags" Option "DontVTSwitch" "true" Option "AllowMouseOpenFail" "true" Option "PciForceNone" "true" Option "AutoEnableDevices" "false" Option "AutoAddDevices" "false" EndSection ##Xdummy:## Section "InputDevice" Identifier "NoMouse" Option "CorePointer" "true" Driver "void" EndSection Section "InputDevice" Identifier "NoKeyboard" Option "CoreKeyboard" "true" Driver "void" EndSection ##Xdummy:## Section "Device" Identifier "Videocard0" Driver "dummy" # In kByte #VideoRam 4096000 #VideoRam 256000 # This should be good for 3840*2560*32bpp: http://winswitch.org/trac/ticket/140 VideoRam 64000 EndSection ##Xdummy:## Section "Monitor" Identifier "Monitor0" HorizSync 10.0 - 300.0 VertRefresh 10.0 - 200.0 DisplaySize 4335 1084 #The following modeline is invalid (calculator overflowed): #Modeline "32000x32000@0" -38917.43 32000 32032 -115848 -115816 32000 32775 32826 33601 Modeline "16384x8192@10" 2101.93 16384 16416 24400 24432 8192 8390 8403 8602 Modeline "8192x4096@10" 424.46 8192 8224 9832 9864 4096 4195 4202 4301 Modeline "5120x3200@10" 199.75 5120 5152 5904 5936 3200 3277 3283 3361 Modeline "3840x2880@10" 133.43 3840 3872 4376 4408 2880 2950 2955 3025 Modeline "3840x2560@10" 116.93 3840 3872 4312 4344 2560 2622 2627 2689 Modeline "3840x2048@10" 91.45 3840 3872 4216 4248 2048 2097 2101 2151 Modeline "2048x2048@10" 49.47 2048 2080 2264 2296 2048 2097 2101 2151 Modeline "2560x1600@10" 47.12 2560 2592 2768 2800 1600 1639 1642 1681 Modeline "1920x1200@10" 26.28 1920 1952 2048 2080 1200 1229 1231 1261 Modeline "1920x1080@10" 23.53 1920 1952 2040 2072 1080 1106 1108 1135 Modeline "1680x1050@10" 20.08 1680 1712 1784 1816 1050 1075 1077 1103 Modeline "1600x900@20" 33.92 1600 1632 1760 1792 900 921 924 946 Modeline "1440x900@20" 30.66 1440 1472 1584 1616 900 921 924 946 Modeline "1360x768@20" 24.49 1360 1392 1480 1512 768 786 789 807 #common resolutions for android devices (both orientations): Modeline "800x1280@20" 25.89 800 832 928 960 1280 1310 1315 1345 Modeline "1280x800@20" 24.15 1280 1312 1400 1432 800 819 822 841 Modeline "720x1280@25" 30.22 720 752 864 896 1280 1309 1315 1345 Modeline "1280x720@25" 27.41 1280 1312 1416 1448 720 737 740 757 Modeline "768x1024@25" 24.93 768 800 888 920 1024 1047 1052 1076 Modeline "1024x768@25" 23.77 1024 1056 1144 1176 768 785 789 807 Modeline "600x1024@25" 19.90 600 632 704 736 1024 1047 1052 1076 Modeline "1024x600@25" 18.26 1024 1056 1120 1152 600 614 617 631 Modeline "536x960@25" 16.74 536 568 624 656 960 982 986 1009 Modeline "960x536@25" 15.23 960 992 1048 1080 536 548 551 563 Modeline "600x800@25" 15.17 600 632 688 720 800 818 822 841 Modeline "800x600@25" 14.50 800 832 880 912 600 614 617 631 Modeline "480x854@25" 13.34 480 512 560 592 854 873 877 897 Modeline "848x480@25" 12.09 848 880 920 952 480 491 493 505 Modeline "480x800@25" 12.43 480 512 552 584 800 818 822 841 Modeline "800x480@25" 11.46 800 832 872 904 480 491 493 505 Modeline "320x480@50" 10.73 320 352 392 424 480 490 494 505 Modeline "480x320@50" 9.79 480 512 544 576 320 327 330 337 Modeline "240x400@50" 6.96 240 272 296 328 400 408 412 421 Modeline "400x240@50" 6.17 400 432 448 480 240 245 247 253 Modeline "240x320@50" 5.47 240 272 288 320 320 327 330 337 Modeline "320x240@50" 5.10 320 352 368 400 240 245 247 253 #resolutions for android devices (both orientations) #minus the status bar #38px status bar (and width rounded up) Modeline "800x1242@20" 25.03 800 832 920 952 1242 1271 1275 1305 Modeline "1280x762@20" 22.93 1280 1312 1392 1424 762 780 783 801 Modeline "720x1242@25" 29.20 720 752 856 888 1242 1271 1276 1305 Modeline "1280x682@25" 25.85 1280 1312 1408 1440 682 698 701 717 Modeline "768x986@25" 23.90 768 800 888 920 986 1009 1013 1036 Modeline "1024x730@25" 22.50 1024 1056 1136 1168 730 747 750 767 Modeline "600x986@25" 19.07 600 632 704 736 986 1009 1013 1036 Modeline "1024x562@25" 17.03 1024 1056 1120 1152 562 575 578 591 Modeline "536x922@25" 16.01 536 568 624 656 922 943 947 969 Modeline "960x498@25" 14.09 960 992 1040 1072 498 509 511 523 Modeline "600x762@25" 14.39 600 632 680 712 762 779 783 801 Modeline "800x562@25" 13.52 800 832 880 912 562 575 578 591 Modeline "480x810@25" 12.59 480 512 552 584 810 828 832 851 Modeline "848x442@25" 11.09 848 880 920 952 442 452 454 465 Modeline "480x762@25" 11.79 480 512 552 584 762 779 783 801 Modeline "800x442@25" 10.51 800 832 864 896 442 452 454 465 #32px status bar (no need for rounding): Modeline "320x448@50" 9.93 320 352 384 416 448 457 461 471 Modeline "480x288@50" 8.75 480 512 544 576 288 294 297 303 #24px status bar: Modeline "240x376@50" 6.49 240 272 296 328 376 384 387 395 Modeline "400x216@50" 5.50 400 432 448 480 216 220 222 227 Modeline "240x296@50" 5.02 240 272 288 320 296 302 305 311 Modeline "320x216@50" 4.55 320 352 368 400 216 220 222 227 EndSection ##Xdummy:## Section "Screen" Identifier "Screen0" Device "Videocard0" Monitor "Monitor0" DefaultDepth 24 SubSection "Display" Viewport 0 0 Depth 24 Modes "32000x32000" "16384x8192" "8192x4096" "5120x3200" "3840x2880" "3840x2560" "3840x2048" "2048x2048" "2560x1600" "1920x1440" "1920x1200" "1920x1080" "1600x1200" "1680x1050" "1600x900" "1400x1050" "1440x900" "1280x1024" "1366x768" "1280x800" "1024x768" "1024x600" "800x600" "320x200" #Virtual 32000 32000 #Virtual 16384 8192 #Virtual 8192 4096 # http://winswitch.org/trac/ticket/140 Virtual 3840 2560 EndSubSection EndSection Section "ServerLayout" Identifier "dummy_layout" Screen "screen0" InputDevice "NoMouse" InputDevice "NoKeyboard" EndSection ''' tmp, xorg_conf = tempfile.mkstemp(prefix='aa-sandbox-xorg.conf-') self.tempfiles.append(xorg_conf) if sys.version_info[0] >= 3: os.write(tmp, bytes(conf, 'utf-8')) else: os.write(tmp, conf) os.close(tmp) xvfb_args.append('--xvfb=Xorg') xvfb_args.append('-dpi 96') # https://www.xpra.org/trac/ticket/163 xvfb_args.append('-nolisten tcp') xvfb_args.append('-noreset') xvfb_args.append('-logfile %s' % os.path.expanduser('~/.xpra/%s.log' % self.display)) xvfb_args.append('-auth %s' % self.new_environ['XAUTHORITY']) xvfb_args.append('-config %s' % xorg_conf) extensions = ['Composite', 'GLX', 'RANDR', 'RENDER', 'SECURITY'] for i in extensions: xvfb_args.append('+extension %s' % i) else: raise AppArmorException("Unsupported X driver '%s'" % self.driver) return xvfb_args def start(self): debug("Searching for '%s'" % 'xpra') rc, report = cmd(['which', 'xpra']) if rc != 0: raise AppArmorException("Could not find '%s'" % 'xpra') if self.driver == "xdummy": # FIXME: is there a better way we can detect this? drv = "/usr/lib/xorg/modules/drivers/dummy_drv.so" debug("Searching for '%s'" % drv) if not os.path.exists(drv): raise AppArmorException("Could not find '%s'" % drv) '''Run any setup code''' SandboxXserver.start(self) xvfb_args = self._get_xvfb_args() listener_x = os.fork() if listener_x == 0: os.environ['XAUTHORITY'] = self.xauth # This will clean out any dead sessions cmd(['xpra', 'list']) x_args = ['--no-daemon', #'--no-mmap', # for security? '--no-pulseaudio'] if not self.clipboard: x_args.append('--no-clipboard') if xvfb_args != '': x_args.append(" ".join(xvfb_args)) args = ['/usr/bin/xpra', 'start', self.display] + x_args debug(" ".join(args)) sys.stderr.flush() os.execv(args[0], args) sys.exit(0) self.pids.append(listener_x) started = False # We need to wait for the xpra socket to exist before attaching fn = os.path.join(os.environ['HOME'], '.xpra', '%s-%s' % \ (socket.gethostname(), self.display.split(':')[1])) for i in range(self.timeout * 2): # up to self.timeout seconds to start if os.path.exists(fn): debug("Found '%s'! Proceeding to attach" % fn) break debug("'%s' doesn't exist yet, waiting" % fn) time.sleep(0.5) if not os.path.exists(fn): sys.stdout.flush() self.cleanup() raise AppArmorException("Could not start xpra (try again with -d)") for i in range(self.timeout): # Up to self.timeout seconds to start rc, out = cmd(['xpra', 'list']) if 'DEAD session at %s' % self.display in out: error("xpra session at '%s' died" % self.display, do_exit=False) break search = 'LIVE session at %s' % self.display if search in out: started = True break time.sleep(0.5) debug("Could not find '%s' in:\n" % search) debug(out) if not started: sys.stdout.flush() self.cleanup() raise AppArmorException("Could not start xpra (try again with -d)") # Next, attach to xpra sys.stdout.flush() os.chdir(os.environ["HOME"]) listener_attach = os.fork() if listener_attach == 0: args = ['/usr/bin/xpra', 'attach', self.display, '--title=%s' % self.generate_title(), #'--no-mmap', # for security? '--no-tray', '--no-pulseaudio'] if not self.clipboard: args.append('--no-clipboard') debug(" ".join(args)) sys.stderr.flush() os.execv(args[0], args) sys.exit(0) self.pids.append(listener_attach) # Make sure that a client has attached for i in range(self.timeout): # up to self.timeout seconds to attach time.sleep(1) rc, out = cmd (['xpra', 'info', self.display]) search = 'clients=1' if search in out: debug("Client successfully attached!") break debug("Could not find '%s' in:\n" % search) debug(out) msg("TODO: filter '~/.xpra/run-xpra'") def run_xsandbox(command, opt): '''Run X application in a sandbox''' old_cwd = os.getcwd() # first, start X if opt.xserver.lower() == "xephyr": x = SandboxXephyr(command[0], geometry=opt.xephyr_geometry, xauth=opt.xauthority) elif opt.xserver.lower() == "xpra3d": x = SandboxXpra(command[0], geometry=None, driver="xdummy", xauth=opt.xauthority, clipboard=opt.with_clipboard) else: x = SandboxXpra(command[0], geometry=None, xauth=opt.xauthority, clipboard=opt.with_clipboard) x.verify_host_setup() # Debug: show old environment keys = x.old_environ.keys() keys.sort() for k in keys: debug ("Old: %s=%s" % (k, x.old_environ[k])) try: x.start() except Exception as e: error(e) os.chdir(old_cwd) if not opt.read_path: opt.read_path = [] opt.read_path.append(x.xauth) # Only used with dynamic profiles required_rules = ['audit deny @{HOME}/.Xauthority mrwlk,'] # aa-exec try: rc, report = aa_exec(command, opt, x.new_environ, required_rules) except Exception: x.cleanup() raise x.cleanup() return rc, report apparmor-2.13.3/utils/apparmor/rule/0000755000175000017500000000000013502024172015135 5ustar jjjjapparmor-2.13.3/utils/apparmor/rule/dbus.py0000644000175000017500000003755213502024172016460 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import re from apparmor.regex import RE_PROFILE_DBUS, RE_PROFILE_NAME, strip_parenthesis, strip_quotes from apparmor.common import AppArmorBug, AppArmorException from apparmor.rule import BaseRule, BaseRuleset, check_and_split_list, logprof_value_or_all, parse_modifiers, quote_if_needed # setup module translations from apparmor.translations import init_translation _ = init_translation() message_keywords = ['send', 'receive', 'r', 'read', 'w', 'write', 'rw'] access_keywords = [ 'bind', 'eavesdrop' ] + message_keywords # XXX joint_access_keyword and RE_ACCESS_KEYWORDS exactly as in SignalRule - move to function? joint_access_keyword = '(' + '(\s|,)*' + '(' + '|'.join(access_keywords) + ')(\s|,)*' + ')' RE_ACCESS_KEYWORDS = ( joint_access_keyword + # one of the access_keyword or '|' + # or '\(' + '(\s|,)*' + joint_access_keyword + '?' + '(' + '(\s|,)+' + joint_access_keyword + ')*' + '\)' # one or more access_keyword in (...) ) RE_FLAG = '(?P<%s>(\S+|"[^"]+"|\(\s*\S+\s*\)|\(\s*"[^"]+"\)\s*))' # string without spaces, or quoted string, optionally wrapped in (...). %s is the match group name # plaintext version: | * | "* " | ( * ) | ( " * " ) | # XXX this regex will allow repeated parameters, last one wins # XXX (the parser will reject such rules) RE_DBUS_DETAILS = re.compile( '^' + '(\s+(?P' + RE_ACCESS_KEYWORDS + '))?' + # optional access keyword(s) '((\s+(bus\s*=\s*' + RE_FLAG % 'bus' + '))?|' + # optional bus= system | session | AARE, (...) optional '(\s+(path\s*=\s*' + RE_FLAG % 'path' + '))?|' + # optional path=AARE, (...) optional '(\s+(name\s*=\s*' + RE_FLAG % 'name' + '))?|' + # optional name=AARE, (...) optional '(\s+(interface\s*=\s*' + RE_FLAG % 'interface' + '))?|' + # optional interface=AARE, (...) optional '(\s+(member\s*=\s*' + RE_FLAG % 'member' + '))?|' + # optional member=AARE, (...) optional '(\s+(peer\s*=\s*\((,|\s)*' + # optional peer=( name=AARE and/or label=AARE ), (...) required '(' + '(' + '(,|\s)*' + ')' + # empty peer=() '|' # or '(' + 'name\s*=\s*' + RE_PROFILE_NAME % 'peername1' + ')' + # only peer name (match group peername1) '|' # or '(' + 'label\s*=\s*' + RE_PROFILE_NAME % 'peerlabel1' + ')' + # only peer label (match group peerlabel1) '|' # or '(' + 'name\s*=\s*' + RE_PROFILE_NAME % 'peername2' + '(,|\s)+' + 'label\s*=\s*' + RE_PROFILE_NAME % 'peerlabel2' + ')' + # peer name + label (match name peername2/peerlabel2) '|' # or '(' + 'label\s*=\s*' + RE_PROFILE_NAME % 'peerlabel3' + '(,|\s)+' + 'name\s*=\s*' + RE_PROFILE_NAME % 'peername3' + ')' + # peer label + name (match name peername3/peerlabel3) ')' '(,|\s)*\)))?){0,6}' '\s*$') class DbusRule(BaseRule): '''Class to handle and store a single dbus rule''' # Nothing external should reference this class, all external users # should reference the class field DbusRule.ALL class __DbusAll(object): pass ALL = __DbusAll rule_name = 'dbus' def __init__(self, access, bus, path, name, interface, member, peername, peerlabel, audit=False, deny=False, allow_keyword=False, comment='', log_event=None): super(DbusRule, self).__init__(audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, log_event=log_event) self.access, self.all_access, unknown_items = check_and_split_list(access, access_keywords, DbusRule.ALL, 'DbusRule', 'access') if unknown_items: raise AppArmorException(_('Passed unknown access keyword to DbusRule: %s') % ' '.join(unknown_items)) # rulepart partname is_path log_event self.bus, self.all_buses = self._aare_or_all(bus, 'bus', False, log_event) self.path, self.all_paths = self._aare_or_all(path, 'path', True, log_event) self.name, self.all_names = self._aare_or_all(name, 'name', False, log_event) self.interface, self.all_interfaces = self._aare_or_all(interface, 'interface', False, log_event) self.member, self.all_members = self._aare_or_all(member, 'member', False, log_event) self.peername, self.all_peernames = self._aare_or_all(peername, 'peer name', False, log_event) self.peerlabel, self.all_peerlabels = self._aare_or_all(peerlabel, 'peer label', False, log_event) # not all combinations are allowed if self.access and 'bind' in self.access and (self.path or self.interface or self.member or self.peername or self.peerlabel): raise AppArmorException(_('dbus bind rules must not contain a path, interface, member or peer conditional')) elif self.access and 'eavesdrop' in self.access and (self.name or self.path or self.interface or self.member or self.peername or self.peerlabel): raise AppArmorException(_('dbus eavesdrop rules must not contain a name, path, interface, member or peer conditional')) elif self.access and self.name: for msg in message_keywords: if msg in self.access: raise AppArmorException(_('dbus %s rules must not contain a name conditional') % '/'.join(self.access)) @classmethod def _match(cls, raw_rule): return RE_PROFILE_DBUS.search(raw_rule) @classmethod def _parse(cls, raw_rule): '''parse raw_rule and return DbusRule''' matches = cls._match(raw_rule) if not matches: raise AppArmorException(_("Invalid dbus rule '%s'") % raw_rule) audit, deny, allow_keyword, comment = parse_modifiers(matches) rule_details = '' if matches.group('details'): rule_details = matches.group('details') if rule_details: details = RE_DBUS_DETAILS.search(rule_details) if not details: raise AppArmorException(_("Invalid or unknown keywords in 'dbus %s" % rule_details)) if details.group('access'): # XXX move to function _split_access()? access = strip_parenthesis(details.group('access')) access = access.replace(',', ' ').split() # split by ',' or whitespace if access == []: # XXX that happens for "dbus ( )," rules - correct behaviour? (also: same for signal rules?) access = DbusRule.ALL else: access = DbusRule.ALL if details.group('bus'): bus = strip_parenthesis(strip_quotes(details.group('bus'))) else: bus = DbusRule.ALL if details.group('path'): path = strip_parenthesis(strip_quotes(details.group('path'))) else: path = DbusRule.ALL if details.group('name'): name = strip_parenthesis(strip_quotes(details.group('name'))) else: name = DbusRule.ALL if details.group('interface'): interface = strip_parenthesis(strip_quotes(details.group('interface'))) else: interface = DbusRule.ALL if details.group('member'): member = strip_parenthesis(strip_quotes(details.group('member'))) else: member = DbusRule.ALL if details.group('peername1'): peername = strip_parenthesis(strip_quotes(details.group('peername1'))) elif details.group('peername2'): peername = strip_parenthesis(strip_quotes(details.group('peername2'))) elif details.group('peername3'): peername = strip_parenthesis(strip_quotes(details.group('peername3'))) else: peername = DbusRule.ALL if details.group('peerlabel1'): peerlabel = strip_parenthesis(strip_quotes(details.group('peerlabel1'))) elif details.group('peerlabel2'): peerlabel = strip_parenthesis(strip_quotes(details.group('peerlabel2'))) elif details.group('peerlabel3'): peerlabel = strip_parenthesis(strip_quotes(details.group('peerlabel3'))) else: peerlabel = DbusRule.ALL else: access = DbusRule.ALL bus = DbusRule.ALL path = DbusRule.ALL name = DbusRule.ALL interface = DbusRule.ALL member = DbusRule.ALL peername = DbusRule.ALL peerlabel = DbusRule.ALL return DbusRule(access, bus, path, name, interface, member, peername, peerlabel, audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment) def get_clean(self, depth=0): '''return rule (in clean/default formatting)''' space = ' ' * depth # XXX split off _get_access_rule_part? (also needed in PtraceRule) if self.all_access: access = '' elif len(self.access) == 1: access = ' %s' % ' '.join(self.access) elif self.access: access = ' (%s)' % ' '.join(sorted(self.access)) else: raise AppArmorBug('Empty access in dbus rule') bus = self._get_aare_rule_part('bus', self.bus, self.all_buses) path = self._get_aare_rule_part('path', self.path, self.all_paths) name = self._get_aare_rule_part('name', self.name, self.all_names) interface = self._get_aare_rule_part('interface', self.interface, self.all_interfaces) member = self._get_aare_rule_part('member', self.member, self.all_members) peername = self._get_aare_rule_part('name', self.peername, self.all_peernames) peerlabel = self._get_aare_rule_part('label', self.peerlabel, self.all_peerlabels) peer = peername + peerlabel if peer: peer = ' peer=(%s)' % peer.strip() return('%s%sdbus%s%s%s%s%s%s%s,%s' % (space, self.modifiers_str(), access, bus, path, name, interface, member, peer, self.comment)) def _get_aare_rule_part(self, prefix, value, all_values): '''helper function to write a rule part value is expected to be a AARE''' if all_values: return '' elif value: return ' %(prefix)s=%(value)s' % {'prefix': prefix, 'value': quote_if_needed(value.regex)} else: raise AppArmorBug('Empty %(prefix_name)s in %(rule_name)s rule' % {'prefix_name': prefix, 'rule_name': self.rule_name}) def is_covered_localvars(self, other_rule): '''check if other_rule is covered by this rule object''' if not self._is_covered_list(self.access, self.all_access, other_rule.access, other_rule.all_access, 'access'): return False if not self._is_covered_aare_compat(self.bus, self.all_buses, other_rule.bus, other_rule.all_buses, 'bus'): return False if not self._is_covered_aare_compat(self.path, self.all_paths, other_rule.path, other_rule.all_paths, 'path'): return False if not self._is_covered_aare_compat(self.name, self.all_names, other_rule.name, other_rule.all_names, 'name'): return False if not self._is_covered_aare_compat(self.interface, self.all_interfaces, other_rule.interface, other_rule.all_interfaces, 'interface'): return False if not self._is_covered_aare_compat(self.member, self.all_members, other_rule.member, other_rule.all_members, 'member'): return False if not self._is_covered_aare_compat(self.peername, self.all_peernames, other_rule.peername, other_rule.all_peernames, 'peername'): return False if not self._is_covered_aare_compat(self.peerlabel, self.all_peerlabels, other_rule.peerlabel, other_rule.all_peerlabels, 'peerlabel'): return False # still here? -> then it is covered return True def is_equal_localvars(self, rule_obj, strict): '''compare if rule-specific variables are equal''' if not type(rule_obj) == DbusRule: raise AppArmorBug('Passed non-dbus rule: %s' % str(rule_obj)) if (self.access != rule_obj.access or self.all_access != rule_obj.all_access): return False if not self._is_equal_aare(self.bus, self.all_buses, rule_obj.bus, rule_obj.all_buses, 'bus'): return False if not self._is_equal_aare(self.path, self.all_paths, rule_obj.path, rule_obj.all_paths, 'path'): return False if not self._is_equal_aare(self.name, self.all_names, rule_obj.name, rule_obj.all_names, 'name'): return False if not self._is_equal_aare(self.interface, self.all_interfaces, rule_obj.interface, rule_obj.all_interfaces, 'interface'): return False if not self._is_equal_aare(self.member, self.all_members, rule_obj.member, rule_obj.all_members, 'member'): return False if not self._is_equal_aare(self.peername, self.all_peernames, rule_obj.peername, rule_obj.all_peernames, 'peername'): return False if not self._is_equal_aare(self.peerlabel, self.all_peerlabels, rule_obj.peerlabel, rule_obj.all_peerlabels, 'peerlabel'): return False return True def logprof_header_localvars(self): access = logprof_value_or_all(self.access, self.all_access) bus = logprof_value_or_all(self.bus, self.all_buses) path = logprof_value_or_all(self.path, self.all_paths) name = logprof_value_or_all(self.name, self.all_names) interface = logprof_value_or_all(self.interface, self.all_interfaces) member = logprof_value_or_all(self.member, self.all_members) peername = logprof_value_or_all(self.peername, self.all_peernames) peerlabel = logprof_value_or_all(self.peerlabel, self.all_peerlabels) return [ _('Access mode'), access, _('Bus'), bus, _('Path'), path, _('Name'), name, _('Interface'), interface, _('Member'), member, _('Peer name'), peername, _('Peer label'), peerlabel, ] class DbusRuleset(BaseRuleset): '''Class to handle and store a collection of dbus rules''' def get_glob(self, path_or_rule): '''Return the next possible glob. For dbus rules, that means removing access or removing/globbing bus''' # XXX only remove one part, not all return 'dbus,' apparmor-2.13.3/utils/apparmor/rule/signal.py0000644000175000017500000002276113502024172016774 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import re from apparmor.regex import RE_PROFILE_SIGNAL, RE_PROFILE_NAME from apparmor.common import AppArmorBug, AppArmorException from apparmor.rule import BaseRule, BaseRuleset, check_and_split_list, logprof_value_or_all, parse_modifiers, quote_if_needed # setup module translations from apparmor.translations import init_translation _ = init_translation() access_keywords_read = ['receive', 'r', 'read'] access_keywords_write = ['send', 'w', 'write'] access_keywords_rw = ['rw', 'wr'] access_keywords = access_keywords_read + access_keywords_write + access_keywords_rw signal_keywords = ['hup', 'int', 'quit', 'ill', 'trap', 'abrt', 'bus', 'fpe', 'kill', 'usr1', 'segv', 'usr2', 'pipe', 'alrm', 'term', 'stkflt', 'chld', 'cont', 'stop', 'stp', 'ttin', 'ttou', 'urg', 'xcpu', 'xfsz', 'vtalrm', 'prof', 'winch', 'io', 'pwr', 'sys', 'emt', 'exists'] RE_SIGNAL_REALTIME = re.compile('^rtmin\+0*([0-9]|[12][0-9]|3[0-2])$') # rtmin+0..rtmin+32, number may have leading zeros joint_access_keyword = '\s*(' + '|'.join(access_keywords) + ')\s*' RE_ACCESS_KEYWORDS = ( joint_access_keyword + # one of the access_keyword or '|' + # or '\(' + joint_access_keyword + '(' + '(\s|,)+' + joint_access_keyword + ')*' + '\)' # one or more access_keyword in (...) ) signal_keyword = '\s*([a-z0-9+]+|"[a-z0-9+]+")\s*' # don't check against the signal keyword list in the regex to allow a more helpful error message RE_SIGNAL_KEYWORDS = ( 'set\s*=\s*' + signal_keyword + # one of the signal_keyword or '|' + # or 'set\s*=\s*\(' + signal_keyword + '(' + '(\s|,)+' + signal_keyword + ')*' + '\)' # one or more signal_keyword in (...) ) RE_SIGNAL_DETAILS = re.compile( '^' + '(\s+(?P' + RE_ACCESS_KEYWORDS + '))?' + # optional access keyword(s) '(?P' + '(\s+(' + RE_SIGNAL_KEYWORDS + '))+' + ')?' + # optional signal set(s) '(\s+(peer=' + RE_PROFILE_NAME % 'peer' + '))?' + # optional peer '\s*$') RE_FILTER_SET_1 = re.compile('set\s*=\s*\(([^)]*)\)') RE_FILTER_SET_2 = re.compile('set\s*=') RE_FILTER_PARENTHESIS = re.compile('\((.*)\)') RE_FILTER_QUOTES = re.compile('"([a-z0-9]+)"') # used to strip quotes around signal keywords - don't use for peer! class SignalRule(BaseRule): '''Class to handle and store a single signal rule''' # Nothing external should reference this class, all external users # should reference the class field SignalRule.ALL class __SignalAll(object): pass ALL = __SignalAll rule_name = 'signal' def __init__(self, access, signal, peer, audit=False, deny=False, allow_keyword=False, comment='', log_event=None): super(SignalRule, self).__init__(audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, log_event=log_event) self.access, self.all_access, unknown_items = check_and_split_list(access, access_keywords, SignalRule.ALL, 'SignalRule', 'access') if unknown_items: raise AppArmorException(_('Passed unknown access keyword to SignalRule: %s') % ' '.join(unknown_items)) self.signal, self.all_signals, unknown_items = check_and_split_list(signal, signal_keywords, SignalRule.ALL, 'SignalRule', 'signal') if unknown_items: for item in unknown_items: if RE_SIGNAL_REALTIME.match(item): self.signal.add(item) else: raise AppArmorException(_('Passed unknown signal keyword to SignalRule: %s') % item) self.peer, self.all_peers = self._aare_or_all(peer, 'peer', is_path=False, log_event=log_event) @classmethod def _match(cls, raw_rule): return RE_PROFILE_SIGNAL.search(raw_rule) @classmethod def _parse(cls, raw_rule): '''parse raw_rule and return SignalRule''' matches = cls._match(raw_rule) if not matches: raise AppArmorException(_("Invalid signal rule '%s'") % raw_rule) audit, deny, allow_keyword, comment = parse_modifiers(matches) rule_details = '' if matches.group('details'): rule_details = matches.group('details') if rule_details: details = RE_SIGNAL_DETAILS.search(rule_details) if not details: raise AppArmorException(_("Invalid or unknown keywords in 'signal %s" % rule_details)) if details.group('access'): access = details.group('access') if access.startswith('(') and access.endswith(')'): access = access[1:-1] access = access.replace(',', ' ').split() # split by ',' or whitespace else: access = SignalRule.ALL if details.group('signal'): signal = details.group('signal') signal = RE_FILTER_SET_1.sub(r'\1', signal) # filter out 'set=' signal = RE_FILTER_SET_2.sub('', signal) # filter out 'set=' signal = RE_FILTER_QUOTES.sub(r' \1 ', signal) # filter out quote pairs signal = signal.replace(',', ' ').split() # split at ',' or whitespace else: signal = SignalRule.ALL if details.group('peer'): peer = details.group('peer') else: peer = SignalRule.ALL else: access = SignalRule.ALL signal = SignalRule.ALL peer = SignalRule.ALL return SignalRule(access, signal, peer, audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment) def get_clean(self, depth=0): '''return rule (in clean/default formatting)''' space = ' ' * depth if self.all_access: access = '' elif len(self.access) == 1: access = ' %s' % ' '.join(self.access) elif self.access: access = ' (%s)' % ' '.join(sorted(self.access)) else: raise AppArmorBug('Empty access in signal rule') if self.all_signals: signal = '' elif len(self.signal) == 1: signal = ' set=%s' % ' '.join(self.signal) elif self.signal: signal = ' set=(%s)' % ' '.join(sorted(self.signal)) else: raise AppArmorBug('Empty signal in signal rule') if self.all_peers: peer = '' elif self.peer: peer = ' peer=%s' % quote_if_needed(self.peer.regex) else: raise AppArmorBug('Empty peer in signal rule') return('%s%ssignal%s%s%s,%s' % (space, self.modifiers_str(), access, signal, peer, self.comment)) def is_covered_localvars(self, other_rule): '''check if other_rule is covered by this rule object''' if not self._is_covered_list(self.access, self.all_access, other_rule.access, other_rule.all_access, 'access'): return False if not self._is_covered_list(self.signal, self.all_signals, other_rule.signal, other_rule.all_signals, 'signal'): return False if not self._is_covered_aare_compat(self.peer, self.all_peers, other_rule.peer, other_rule.all_peers, 'peer'): return False # still here? -> then it is covered return True def is_equal_localvars(self, rule_obj, strict): '''compare if rule-specific variables are equal''' if not type(rule_obj) == SignalRule: raise AppArmorBug('Passed non-signal rule: %s' % str(rule_obj)) if (self.access != rule_obj.access or self.all_access != rule_obj.all_access): return False if (self.signal != rule_obj.signal or self.all_signals != rule_obj.all_signals): return False if not self._is_equal_aare(self.peer, self.all_peers, rule_obj.peer, rule_obj.all_peers, 'peer'): return False return True def logprof_header_localvars(self): access = logprof_value_or_all(self.access, self.all_access) signal = logprof_value_or_all(self.signal, self.all_signals) peer = logprof_value_or_all(self.peer, self.all_peers) return [ _('Access mode'), access, _('Signal'), signal, _('Peer'), peer ] class SignalRuleset(BaseRuleset): '''Class to handle and store a collection of signal rules''' def get_glob(self, path_or_rule): '''Return the next possible glob. For signal rules, that means removing access, signal or peer''' # XXX only remove one part, not all return 'signal,' apparmor-2.13.3/utils/apparmor/rule/change_profile.py0000644000175000017500000001747313502024172020470 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- from apparmor.regex import RE_PROFILE_CHANGE_PROFILE, strip_quotes from apparmor.common import AppArmorBug, AppArmorException, type_is_str from apparmor.rule import BaseRule, BaseRuleset, parse_modifiers, logprof_value_or_all, quote_if_needed # setup module translations from apparmor.translations import init_translation _ = init_translation() class ChangeProfileRule(BaseRule): '''Class to handle and store a single change_profile rule''' # Nothing external should reference this class, all external users # should reference the class field ChangeProfileRule.ALL class __ChangeProfileAll(object): pass ALL = __ChangeProfileAll rule_name = 'change_profile' equiv_execmodes = [ 'safe', '', None ] def __init__(self, execmode, execcond, targetprofile, audit=False, deny=False, allow_keyword=False, comment='', log_event=None): ''' CHANGE_PROFILE RULE = 'change_profile' [ [ EXEC MODE ] EXEC COND ] [ -> PROGRAMCHILD ] ''' super(ChangeProfileRule, self).__init__(audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, log_event=log_event) if execmode: if execmode != 'safe' and execmode != 'unsafe': raise AppArmorBug('Unknown exec mode (%s) in change_profile rule' % execmode) elif not execcond or execcond == ChangeProfileRule.ALL: raise AppArmorException('Exec condition is required when unsafe or safe keywords are present') self.execmode = execmode self.execcond = None self.all_execconds = False if execcond == ChangeProfileRule.ALL: self.all_execconds = True elif type_is_str(execcond): if not execcond.strip(): raise AppArmorBug('Empty exec condition in change_profile rule') elif execcond.startswith('/') or execcond.startswith('@'): self.execcond = execcond else: raise AppArmorException('Exec condition in change_profile rule does not start with /: %s' % str(execcond)) else: raise AppArmorBug('Passed unknown object to ChangeProfileRule: %s' % str(execcond)) self.targetprofile = None self.all_targetprofiles = False if targetprofile == ChangeProfileRule.ALL: self.all_targetprofiles = True elif type_is_str(targetprofile): if targetprofile.strip(): self.targetprofile = targetprofile else: raise AppArmorBug('Empty target profile in change_profile rule') else: raise AppArmorBug('Passed unknown object to ChangeProfileRule: %s' % str(targetprofile)) @classmethod def _match(cls, raw_rule): return RE_PROFILE_CHANGE_PROFILE.search(raw_rule) @classmethod def _parse(cls, raw_rule): '''parse raw_rule and return ChangeProfileRule''' matches = cls._match(raw_rule) if not matches: raise AppArmorException(_("Invalid change_profile rule '%s'") % raw_rule) audit, deny, allow_keyword, comment = parse_modifiers(matches) execmode = matches.group('execmode') if matches.group('execcond'): execcond = strip_quotes(matches.group('execcond')) else: execcond = ChangeProfileRule.ALL if matches.group('targetprofile'): targetprofile = strip_quotes(matches.group('targetprofile')) else: targetprofile = ChangeProfileRule.ALL return ChangeProfileRule(execmode, execcond, targetprofile, audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment) def get_clean(self, depth=0): '''return rule (in clean/default formatting)''' space = ' ' * depth if self.execmode: execmode = ' %s' % self.execmode else: execmode = '' if self.all_execconds: execcond = '' elif self.execcond: execcond = ' %s' % quote_if_needed(self.execcond) else: raise AppArmorBug('Empty execcond in change_profile rule') if self.all_targetprofiles: targetprofile = '' elif self.targetprofile: targetprofile = ' -> %s' % quote_if_needed(self.targetprofile) else: raise AppArmorBug('Empty target profile in change_profile rule') return('%s%schange_profile%s%s%s,%s' % (space, self.modifiers_str(), execmode, execcond, targetprofile, self.comment)) def is_covered_localvars(self, other_rule): '''check if other_rule is covered by this rule object''' if self.execmode != other_rule.execmode and \ (self.execmode not in ChangeProfileRule.equiv_execmodes or \ other_rule.execmode not in ChangeProfileRule.equiv_execmodes): return False if not self._is_covered_plain(self.execcond, self.all_execconds, other_rule.execcond, other_rule.all_execconds, 'exec condition'): # TODO: honor globbing and variables return False if not self._is_covered_plain(self.targetprofile, self.all_targetprofiles, other_rule.targetprofile, other_rule.all_targetprofiles, 'target profile'): return False # still here? -> then it is covered return True def is_equal_localvars(self, rule_obj, strict): '''compare if rule-specific variables are equal''' if not type(rule_obj) == ChangeProfileRule: raise AppArmorBug('Passed non-change_profile rule: %s' % str(rule_obj)) if self.execmode != rule_obj.execmode and \ (self.execmode not in ChangeProfileRule.equiv_execmodes or \ rule_obj.execmode not in ChangeProfileRule.equiv_execmodes): return False if (self.execcond != rule_obj.execcond or self.all_execconds != rule_obj.all_execconds): return False if (self.targetprofile != rule_obj.targetprofile or self.all_targetprofiles != rule_obj.all_targetprofiles): return False return True def logprof_header_localvars(self): headers = [] if self.execmode: headers += [_('Exec Mode'), self.execmode] execcond_txt = logprof_value_or_all(self.execcond, self.all_execconds) targetprofiles_txt = logprof_value_or_all(self.targetprofile, self.all_targetprofiles) return headers + [ _('Exec Condition'), execcond_txt, _('Target Profile'), targetprofiles_txt, ] class ChangeProfileRuleset(BaseRuleset): '''Class to handle and store a collection of change_profile rules''' def get_glob(self, path_or_rule): '''Return the next possible glob. For change_profile rules, that can be "change_profile EXECCOND,", "change_profile -> TARGET_PROFILE," or "change_profile," (all change_profile). Also, EXECCOND filename can be globbed''' # XXX implement all options mentioned above ;-) return 'change_profile,' apparmor-2.13.3/utils/apparmor/rule/__init__.py0000644000175000017500000005106713502024172017257 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2014 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- from apparmor.aare import AARE from apparmor.common import AppArmorBug, type_is_str # setup module translations from apparmor.translations import init_translation _ = init_translation() class BaseRule(object): '''Base class to handle and store a single rule''' # type specific rules should inherit from this class. # Methods that subclasses need to implement: # __init__ # _match(cls, raw_rule) (as a class method) # - parses a raw rule and returns a regex match object # _parse(cls, raw_rule) (as a class method) # - parses a raw rule and returns an object of the Rule subclass # get_clean(depth) # - return rule in clean format # is_covered(self, other_rule) # - check if other_rule is covered by this rule (i.e. is a # subset of this rule's permissions) # is_equal_localvars(self, other_rule) # - equality check for the rule-specific fields # decides if the (G)lob and Glob w/ (E)xt options are displayed can_glob = False can_glob_ext = False # defines if the (N)ew option is displayed can_edit = False # defines if the '(O)wner permissions on/off' option is displayed can_owner = False def __init__(self, audit=False, deny=False, allow_keyword=False, comment='', log_event=None): '''initialize variables needed by all rule types''' self.audit = audit self.deny = deny self.allow_keyword = allow_keyword self.comment = comment self.log_event = log_event # Set only in the parse() class method self.raw_rule = None def _aare_or_all(self, rulepart, partname, is_path, log_event): '''checks rulepart and returns - (AARE, False) if rulepart is a (non-empty) string - (None, True) if rulepart is all_obj (typically *Rule.ALL) - raises AppArmorBug if rulepart is an empty string or has a wrong type Parameters: - rulepart: the rule part to check (string or *Rule.ALL object) - partname: the name of the rulepart (for example 'peer', used for exception messages) - is_path (passed through to AARE) - log_event (passed through to AARE) ''' if rulepart == self.ALL: return None, True elif type_is_str(rulepart): if len(rulepart.strip()) == 0: raise AppArmorBug('Passed empty %(partname)s to %(classname)s: %(rulepart)s' % {'partname': partname, 'classname': self.__class__.__name__, 'rulepart': str(rulepart)}) return AARE(rulepart, is_path=is_path, log_event=log_event), False else: raise AppArmorBug('Passed unknown %(partname)s to %(classname)s: %(rulepart)s' % {'partname': partname, 'classname': self.__class__.__name__, 'rulepart': str(rulepart)}) def __repr__(self): classname = self.__class__.__name__ try: raw_content = self.get_raw() # will fail for BaseRule return '<%s> %s' % (classname, raw_content) except NotImplementedError: return '<%s (NotImplementedError - get_clean() not implemented?)>' % classname @classmethod def match(cls, raw_rule): '''return True if raw_rule matches the class (main) regex, False otherwise Note: This function just provides an answer to "is this your job?". It does not guarantee that the rule is completely valid.''' if cls._match(raw_rule): return True else: return False # @abstractmethod FIXME - uncomment when python3 only @classmethod def _match(cls, raw_rule): '''parse raw_rule and return regex match object''' raise NotImplementedError("'%s' needs to implement _match(), but didn't" % (str(cls))) @classmethod def parse(cls, raw_rule): '''parse raw_rule and return a rule object''' rule = cls._parse(raw_rule) rule.raw_rule = raw_rule.strip() return rule # @abstractmethod FIXME - uncomment when python3 only @classmethod def _parse(cls, raw_rule): '''returns a Rule object created from parsing the raw rule. required to be implemented by subclasses; raise exception if not''' raise NotImplementedError("'%s' needs to implement _parse(), but didn't" % (str(cls))) # @abstractmethod FIXME - uncomment when python3 only def get_clean(self, depth=0): '''return clean rule (with default formatting, and leading whitespace as specified in the depth parameter)''' raise NotImplementedError("'%s' needs to implement get_clean(), but didn't" % (str(self.__class__))) def get_raw(self, depth=0): '''return raw rule (with original formatting, and leading whitespace in the depth parameter)''' if self.raw_rule: return '%s%s' % (' ' * depth, self.raw_rule) else: return self.get_clean(depth) def is_covered(self, other_rule, check_allow_deny=True, check_audit=False): '''check if other_rule is covered by this rule object''' if not type(other_rule) == type(self): raise AppArmorBug('Passes %s instead of %s' % (str(other_rule),self.__class__.__name__)) if check_allow_deny and self.deny != other_rule.deny: return False if other_rule.deny and not self.deny: return False if check_audit and other_rule.audit != self.audit: return False if other_rule.audit and not self.audit: return False # still here? -> then the common part is covered, check rule-specific things now return self.is_covered_localvars(other_rule) # @abstractmethod FIXME - uncomment when python3 only def is_covered_localvars(self, other_rule): '''check if the rule-specific parts of other_rule is covered by this rule object''' raise NotImplementedError("'%s' needs to implement is_covered_localvars(), but didn't" % (str(self))) def _is_covered_plain(self, self_value, self_all, other_value, other_all, cond_name): '''check if other_* is covered by self_* - for plain str, int etc.''' if not other_value and not other_all: raise AppArmorBug('No %(cond_name)s specified in other %(rule_name)s rule' % {'cond_name': cond_name, 'rule_name': self.rule_name}) if not self_all: if other_all: return False if self_value != other_value: return False # still here? -> then it is covered return True def _is_covered_list(self, self_value, self_all, other_value, other_all, cond_name, sanity_check=True): '''check if other_* is covered by self_* - for lists''' if sanity_check and not other_value and not other_all: raise AppArmorBug('No %(cond_name)s specified in other %(rule_name)s rule' % {'cond_name': cond_name, 'rule_name': self.rule_name}) if not self_all: if other_all: return False if not other_value.issubset(self_value): return False # still here? -> then it is covered return True def _is_covered_aare_compat(self, self_value, self_all, other_value, other_all, cond_name): '''check if other_* is covered by self_* - for AARE Note: this function checks against other_value.regex, which is not really correct, but avoids overly strict results when matching one regex against another ''' if type(other_value) == AARE: other_value = other_value.regex return self._is_covered_aare(self_value, self_all, other_value, other_all, cond_name) def _is_covered_aare(self, self_value, self_all, other_value, other_all, cond_name): '''check if other_* is covered by self_* - for AARE''' if not other_value and not other_all: raise AppArmorBug('No %(cond_name)s specified in other %(rule_name)s rule' % {'cond_name': cond_name, 'rule_name': self.rule_name}) if not self_all: if other_all: return False if not self_value.match(other_value): return False # still here? -> then it is covered return True def is_equal(self, rule_obj, strict=False): '''compare if rule_obj == self Calls is_equal_localvars() to compare rule-specific variables''' if self.audit != rule_obj.audit or self.deny != rule_obj.deny: return False if strict and ( self.allow_keyword != rule_obj.allow_keyword or self.comment != rule_obj.comment or self.raw_rule != rule_obj.raw_rule ): return False return self.is_equal_localvars(rule_obj, strict) def _is_equal_aare(self, self_value, self_all, other_value, other_all, cond_name): '''check if other_* is the same as self_* - for AARE''' if not other_value and not other_all: raise AppArmorBug('No %(cond_name)s specified in other %(rule_name)s rule' % {'cond_name': cond_name, 'rule_name': self.rule_name}) if self_all != other_all: return False if self_value and not self_value.is_equal(other_value): return False # still here? -> then it is equal return True # @abstractmethod FIXME - uncomment when python3 only def is_equal_localvars(self, other_rule, strict): '''compare if rule-specific variables are equal''' raise NotImplementedError("'%s' needs to implement is_equal_localvars(), but didn't" % (str(self))) def severity(self, sev_db): '''return severity of this rule, which can be: - a number between 0 and 10, where 0 means harmless and 10 means critical, - "unknown" (to be exact: the value specified for "unknown" as set when loading the severity database), or - sev_db.NOT_IMPLEMENTED if no severity check is implemented for this rule type. sev_db must be an apparmor.severity.Severity object.''' return sev_db.NOT_IMPLEMENTED def logprof_header(self): '''return the headers (human-readable version of the rule) to display in aa-logprof for this rule object returns {'label1': 'value1', 'label2': 'value2'} ''' headers = [] qualifier = [] if self.audit: qualifier += ['audit'] if self.deny: qualifier += ['deny'] elif self.allow_keyword: qualifier += ['allow'] if qualifier: headers += [_('Qualifier'), ' '.join(qualifier)] headers += self.logprof_header_localvars() return headers # @abstractmethod FIXME - uncomment when python3 only def logprof_header_localvars(self): '''return the headers (human-readable version of the rule) to display in aa-logprof for this rule object returns {'label1': 'value1', 'label2': 'value2'} ''' raise NotImplementedError("'%s' needs to implement logprof_header(), but didn't" % (str(self))) # @abstractmethod FIXME - uncomment when python3 only def edit_header(self): '''return the prompt for, and the path to edit when using '(N)ew' ''' raise NotImplementedError("'%s' needs to implement edit_header(), but didn't" % (str(self))) # @abstractmethod FIXME - uncomment when python3 only def validate_edit(self, newpath): '''validate the new path. Returns True if it covers the previous path, False if it doesn't.''' raise NotImplementedError("'%s' needs to implement validate_edit(), but didn't" % (str(self))) # @abstractmethod FIXME - uncomment when python3 only def store_edit(self, newpath): '''store the changed path. This is done even if the new path doesn't match the original one.''' raise NotImplementedError("'%s' needs to implement store_edit(), but didn't" % (str(self))) def modifiers_str(self): '''return the allow/deny and audit keyword as string, including whitespace''' if self.audit: auditstr = 'audit ' else: auditstr = '' if self.deny: allowstr = 'deny ' elif self.allow_keyword: allowstr = 'allow ' else: allowstr = '' return '%s%s' % (auditstr, allowstr) class BaseRuleset(object): '''Base class to handle and store a collection of rules''' # decides if the (G)lob and Glob w/ (E)xt options are displayed # XXX TODO: remove in all *Ruleset classes (moved to *Rule) can_glob = True can_glob_ext = False def __init__(self): '''initialize variables needed by all ruleset types Do not override in child class unless really needed - override _init_vars() instead''' self.rules = [] self._init_vars() def _init_vars(self): '''called by __init__() and delete_all_rules() - override in child class to initialize more variables''' pass def __repr__(self): classname = self.__class__.__name__ if self.rules: return '<%s>\n' % classname + '\n'.join(self.get_raw(1)) + '' % classname else: return '<%s (empty) />' % classname def add(self, rule, cleanup=False): '''add a rule object if cleanup is specified, delete rules that are covered by the new rule (the difference to delete_duplicates() is: cleanup only deletes rules that are covered by the new rule, but keeps other, unrelated superfluous rules) ''' deleted = 0 if cleanup: oldrules = self.rules self.rules = [] for oldrule in oldrules: if not rule.is_covered(oldrule): self.rules.append(oldrule) else: deleted += 1 self.rules.append(rule) return deleted def get_raw(self, depth=0): '''return all raw rules (if possible/not modified in their original formatting). Returns an array of lines, with depth * leading whitespace''' data = [] for rule in self.rules: data.append(rule.get_raw(depth)) if data: data.append('') return data def get_clean(self, depth=0): '''return all rules (in clean/default formatting) Returns an array of lines, with depth * leading whitespace''' allow_rules = [] deny_rules = [] for rule in self.rules: if rule.deny: deny_rules.append(rule.get_clean(depth)) else: allow_rules.append(rule.get_clean(depth)) allow_rules.sort() deny_rules.sort() cleandata = [] if deny_rules: cleandata += deny_rules cleandata.append('') if allow_rules: cleandata += allow_rules cleandata.append('') return cleandata def is_covered(self, rule, check_allow_deny=True, check_audit=False): '''return True if rule is covered by existing rules, otherwise False''' for r in self.rules: if r.is_covered(rule, check_allow_deny, check_audit): return True return False # def is_log_covered(self, parsed_log_event, check_allow_deny=True, check_audit=False): # '''return True if parsed_log_event is covered by existing rules, otherwise False''' # # rule_obj = self.new_rule() # rule_obj.set_log(parsed_log_event) # # return self.is_covered(rule_obj, check_allow_deny, check_audit) def delete(self, rule): '''Delete rule from rules''' rule_to_delete = False i = 0 for r in self.rules: if r.is_equal(rule): rule_to_delete = True break i = i + 1 if rule_to_delete: self.rules.pop(i) else: raise AppArmorBug('Attempt to delete non-existing rule %s' % rule.get_raw(0)) def delete_duplicates(self, include_rules): '''Delete duplicate rules. include_rules must be a *_rules object or None''' deleted = 0 # delete rules that are covered by include files if include_rules: oldrules = self.rules self.rules = [] for rule in oldrules: if include_rules.is_covered(rule, True, False): deleted += 1 else: self.rules.append(rule) # de-duplicate rules inside the profile deleted += self.delete_in_profile_duplicates() self.rules.reverse() deleted += self.delete_in_profile_duplicates() # search again in reverse order - this will find the remaining duplicates self.rules.reverse() # restore original order for raw output return deleted def delete_in_profile_duplicates(self): '''Delete duplicate rules inside a profile''' deleted = 0 oldrules = self.rules self.rules = [] for rule in oldrules: if not self.is_covered(rule, True, False): self.rules.append(rule) else: deleted += 1 return deleted def get_glob_ext(self, path_or_rule): '''returns the next possible glob with extension (for file rules only). For all other rule types, raise an exception''' raise NotImplementedError("get_glob_ext is not available for this rule type!") def check_and_split_list(lst, allowed_keywords, all_obj, classname, keyword_name, allow_empty_list=False): '''check if lst is all_obj or contains only items listed in allowed_keywords''' if lst == all_obj: return None, True, None elif type_is_str(lst): result_list = {lst} elif type(lst) in [list, tuple, set] and (len(lst) > 0 or allow_empty_list): result_list = set(lst) else: raise AppArmorBug('Passed unknown %(type)s object to %(classname)s: %(unknown_object)s' % {'type': type(lst), 'classname': classname, 'unknown_object': str(lst)}) unknown_items = set() for item in result_list: if not item.strip(): raise AppArmorBug('Passed empty %(keyword_name)s to %(classname)s' % {'keyword_name': keyword_name, 'classname': classname}) if item not in allowed_keywords: unknown_items.add(item) return result_list, False, unknown_items def logprof_value_or_all(value, all_values): '''helper for logprof_header() to return 'all' (if all_values is True) or the specified value. For some types, the value is made more readable.''' if all_values: return _('ALL') if type(value) == AARE: return value.regex elif type(value) == set or type(value) == list or type(value) == tuple: return ' '.join(sorted(value)) else: return value def parse_comment(matches): '''returns the comment (with a leading space) from the matches object''' comment = '' if matches.group('comment'): # include a space so that we don't need to add it everywhere when writing the rule comment = ' %s' % matches.group('comment') return comment def parse_modifiers(matches): '''returns audit, deny, allow_keyword and comment from the matches object - audit, deny and allow_keyword are True/False - comment is the comment with a leading space''' audit = False if matches.group('audit'): audit = True deny = False allow_keyword = False allowstr = matches.group('allow') if allowstr: if allowstr.strip() == 'allow': allow_keyword = True elif allowstr.strip() == 'deny': deny = True else: raise AppArmorBug("Invalid allow/deny keyword %s" % allowstr) comment = parse_comment(matches) return (audit, deny, allow_keyword, comment) def quote_if_needed(data): '''quote data if it contains whitespace''' if ' ' in data: data = '"' + data + '"' return data apparmor-2.13.3/utils/apparmor/rule/ptrace.py0000644000175000017500000001531213502024172016767 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import re from apparmor.regex import RE_PROFILE_PTRACE, RE_PROFILE_NAME, strip_quotes from apparmor.common import AppArmorBug, AppArmorException from apparmor.rule import BaseRule, BaseRuleset, check_and_split_list, logprof_value_or_all, parse_modifiers, quote_if_needed # setup module translations from apparmor.translations import init_translation _ = init_translation() access_keywords = ['r', 'w', 'rw', 'wr', 'read', 'write', 'readby', 'trace', 'tracedby'] # XXX 'wr' and 'write' accepted by the parser, but not documented in apparmor.d.pod # XXX joint_access_keyword and RE_ACCESS_KEYWORDS exactly as in PtraceRule - move to function! joint_access_keyword = '\s*(' + '|'.join(access_keywords) + ')\s*' RE_ACCESS_KEYWORDS = ( joint_access_keyword + # one of the access_keyword or '|' + # or '\(' + joint_access_keyword + '(' + '(\s|,)+' + joint_access_keyword + ')*' + '\)' # one or more access_keyword in (...) ) RE_PTRACE_DETAILS = re.compile( '^' + '(\s+(?P' + RE_ACCESS_KEYWORDS + '))?' + # optional access keyword(s) '(\s+(peer=' + RE_PROFILE_NAME % 'peer' + '))?' + # optional peer '\s*$') class PtraceRule(BaseRule): '''Class to handle and store a single ptrace rule''' # Nothing external should reference this class, all external users # should reference the class field PtraceRule.ALL class __PtraceAll(object): pass ALL = __PtraceAll rule_name = 'ptrace' def __init__(self, access, peer, audit=False, deny=False, allow_keyword=False, comment='', log_event=None): super(PtraceRule, self).__init__(audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, log_event=log_event) self.access, self.all_access, unknown_items = check_and_split_list(access, access_keywords, PtraceRule.ALL, 'PtraceRule', 'access') if unknown_items: raise AppArmorException(_('Passed unknown access keyword to PtraceRule: %s') % ' '.join(unknown_items)) self.peer, self.all_peers = self._aare_or_all(peer, 'peer', is_path=False, log_event=log_event) @classmethod def _match(cls, raw_rule): return RE_PROFILE_PTRACE.search(raw_rule) @classmethod def _parse(cls, raw_rule): '''parse raw_rule and return PtraceRule''' matches = cls._match(raw_rule) if not matches: raise AppArmorException(_("Invalid ptrace rule '%s'") % raw_rule) audit, deny, allow_keyword, comment = parse_modifiers(matches) rule_details = '' if matches.group('details'): rule_details = matches.group('details') if rule_details: details = RE_PTRACE_DETAILS.search(rule_details) if not details: raise AppArmorException(_("Invalid or unknown keywords in 'ptrace %s" % rule_details)) if details.group('access'): # XXX move to function _split_access()? access = details.group('access') if access.startswith('(') and access.endswith(')'): access = access[1:-1] access = access.replace(',', ' ').split() # split by ',' or whitespace else: access = PtraceRule.ALL if details.group('peer'): peer = strip_quotes(details.group('peer')) else: peer = PtraceRule.ALL else: access = PtraceRule.ALL peer = PtraceRule.ALL return PtraceRule(access, peer, audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment) def get_clean(self, depth=0): '''return rule (in clean/default formatting)''' space = ' ' * depth if self.all_access: access = '' elif len(self.access) == 1: access = ' %s' % ' '.join(self.access) elif self.access: access = ' (%s)' % ' '.join(sorted(self.access)) else: raise AppArmorBug('Empty access in ptrace rule') if self.all_peers: peer = '' elif self.peer: peer = ' peer=%s' % quote_if_needed(self.peer.regex) else: raise AppArmorBug('Empty peer in ptrace rule') return('%s%sptrace%s%s,%s' % (space, self.modifiers_str(), access, peer, self.comment)) def is_covered_localvars(self, other_rule): '''check if other_rule is covered by this rule object''' if not self._is_covered_list(self.access, self.all_access, other_rule.access, other_rule.all_access, 'access'): return False if not self._is_covered_aare_compat(self.peer, self.all_peers, other_rule.peer, other_rule.all_peers, 'peer'): return False # still here? -> then it is covered return True def is_equal_localvars(self, rule_obj, strict): '''compare if rule-specific variables are equal''' if not type(rule_obj) == PtraceRule: raise AppArmorBug('Passed non-ptrace rule: %s' % str(rule_obj)) if (self.access != rule_obj.access or self.all_access != rule_obj.all_access): return False if not self._is_equal_aare(self.peer, self.all_peers, rule_obj.peer, rule_obj.all_peers, 'peer'): return False return True def logprof_header_localvars(self): access = logprof_value_or_all(self.access,self.all_access) peer = logprof_value_or_all(self.peer, self.all_peers) return [ _('Access mode'), access, _('Peer'), peer ] class PtraceRuleset(BaseRuleset): '''Class to handle and store a collection of ptrace rules''' def get_glob(self, path_or_rule): '''Return the next possible glob. For ptrace rules, that means removing access or removing/globbing peer''' # XXX only remove one part, not all return 'ptrace,' apparmor-2.13.3/utils/apparmor/rule/rlimit.py0000644000175000017500000002370213502024172017013 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import re from apparmor.regex import RE_PROFILE_RLIMIT, strip_quotes from apparmor.common import AppArmorBug, AppArmorException, type_is_str from apparmor.rule import BaseRule, BaseRuleset, parse_comment, quote_if_needed # setup module translations from apparmor.translations import init_translation _ = init_translation() rlimit_size = ['fsize', 'data', 'stack', 'core', 'rss', 'as', 'memlock', 'msgqueue'] # NUMBER ( 'K' | 'M' | 'G' ) rlimit_number = ['ofile', 'nofile', 'locks', 'sigpending', 'nproc', 'rtprio'] rlimit_time = ['cpu', 'rttime'] # number + time unit (cpu in seconds+, rttime in us+) rlimit_nice = ['nice'] # a number between -20 and 19. rlimit_all = rlimit_size + rlimit_number + rlimit_time + rlimit_nice RE_NUMBER_UNIT = re.compile('^(?P[0-9]+)\s*(?P[a-zA-Z]*)$') RE_NUMBER = re.compile('^[0-9]+$') RE_UNIT_SIZE = re.compile('^[0-9]+\s*([KMG]B?)?$') RE_NICE = re.compile('^(-20|-[01]?[0-9]|[01]?[0-9])$') class RlimitRule(BaseRule): '''Class to handle and store a single rlimit rule''' # Nothing external should reference this class, all external users # should reference the class field RlimitRule.ALL class __RlimitAll(object): pass ALL = __RlimitAll rule_name = 'rlimit' def __init__(self, rlimit, value, audit=False, deny=False, allow_keyword=False, comment='', log_event=None): super(RlimitRule, self).__init__(audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, log_event=log_event) if audit or deny or allow_keyword: raise AppArmorBug('The audit, allow or deny keywords are not allowed in rlimit rules.') if type_is_str(rlimit): if rlimit in rlimit_all: self.rlimit = rlimit else: raise AppArmorException('Unknown rlimit keyword in rlimit rule: %s' % rlimit) else: raise AppArmorBug('Passed unknown object to RlimitRule: %s' % str(rlimit)) self.value = None self.value_as_int = None self.all_values = False if value == RlimitRule.ALL: self.all_values = True elif type_is_str(value): if not value.strip(): raise AppArmorBug('Empty value in rlimit rule') elif rlimit in rlimit_size: if not RE_UNIT_SIZE.match(value): raise AppArmorException('Invalid value or unit in rlimit %s %s rule' % (rlimit, value)) self.value_as_int = self.size_to_int(value) elif rlimit in rlimit_number: if not RE_NUMBER.match(value): raise AppArmorException('Invalid value in rlimit %s %s rule' % (rlimit, value)) self.value_as_int = int(value) elif rlimit in rlimit_time: if not RE_NUMBER_UNIT.match(value): raise AppArmorException('Invalid value in rlimit %s %s rule' % (rlimit, value)) number, unit = split_unit(value) if rlimit == 'rttime': self.value_as_int = self.time_to_int(value, 'us') else: self.value_as_int = self.time_to_int(value, 'seconds') elif rlimit in rlimit_nice: # pragma: no branch - "if rlimit in rlimit_all:" above avoids the need for an "else:" branch if not RE_NICE.match(value): raise AppArmorException('Invalid value or unit in rlimit %s %s rule' % (rlimit, value)) self.value_as_int = 0 - int(value) # lower numbers mean a higher limit for nice # still here? fine :-) self.value = value else: raise AppArmorBug('Passed unknown object to RlimitRule: %s' % str(value)) @classmethod def _match(cls, raw_rule): return RE_PROFILE_RLIMIT.search(raw_rule) @classmethod def _parse(cls, raw_rule): '''parse raw_rule and return RlimitRule''' matches = cls._match(raw_rule) if not matches: raise AppArmorException(_("Invalid rlimit rule '%s'") % raw_rule) comment = parse_comment(matches) if matches.group('rlimit'): rlimit = strip_quotes(matches.group('rlimit')) else: raise AppArmorException(_("Invalid rlimit rule '%s' - keyword missing") % raw_rule) # pragma: no cover - would need breaking the regex if matches.group('value'): if matches.group('value') == 'infinity': value = RlimitRule.ALL else: value = strip_quotes(matches.group('value')) else: raise AppArmorException(_("Invalid rlimit rule '%s' - value missing") % raw_rule) # pragma: no cover - would need breaking the regex return RlimitRule(rlimit, value, comment=comment) def get_clean(self, depth=0): '''return rule (in clean/default formatting)''' space = ' ' * depth if self.rlimit: rlimit = ' %s' % quote_if_needed(self.rlimit) else: raise AppArmorBug('Empty rlimit in rlimit rule') if self.all_values: value = ' <= infinity' elif self.value: value = ' <= %s' % quote_if_needed(self.value) else: raise AppArmorBug('Empty value in rlimit rule') return('%s%sset rlimit%s%s,%s' % (space, self.modifiers_str(), rlimit, value, self.comment)) def size_to_int(self, value): number, unit = split_unit(value) if unit == '': pass elif unit == 'K' or unit == 'KB': number = number * 1024 elif unit == 'M' or unit == 'MB': number = number * 1024 * 1024 elif unit == 'G' or unit == 'GB': number = number * 1024 * 1024 * 1024 else: raise AppArmorException('Unknown unit %s in rlimit %s %s' % (unit, self.rlimit, value)) return number def time_to_int(self, value, default_unit): number, unit = split_unit(value) if unit == '': unit = default_unit if unit in ['us', 'microsecond', 'microseconds']: number = number / 1000000.0 if default_unit == 'seconds': raise AppArmorException(_('Invalid unit in rlimit cpu %s rule') % value) elif unit in ['ms', 'millisecond', 'milliseconds']: number = number / 1000.0 if default_unit == 'seconds': raise AppArmorException(_('Invalid unit in rlimit cpu %s rule') % value) elif unit in ['s', 'sec', 'second', 'seconds']: # manpage doesn't list sec pass elif unit in ['min', 'minute', 'minutes']: number = number * 60 elif unit in ['h', 'hour', 'hours']: number = number * 60 * 60 elif unit in ['d', 'day', 'days']: # manpage doesn't list 'd' number = number * 60 * 60 * 24 elif unit in ['week', 'weeks']: number = number * 60 * 60 * 24 * 7 else: raise AppArmorException('Unknown unit %s in rlimit %s %s' % (unit, self.rlimit, value)) return number def is_covered_localvars(self, other_rule): '''check if other_rule is covered by this rule object''' if not self._is_covered_plain(self.rlimit, False, other_rule.rlimit, False, 'rlimit'): # rlimit can't be ALL, therefore using False return False if not other_rule.value and not other_rule.all_values: raise AppArmorBug('No target profile specified in other rlimit rule') if not self.all_values: if other_rule.all_values: return False if other_rule.value_as_int > self.value_as_int: return False # still here? -> then it is covered return True def is_equal_localvars(self, rule_obj, strict): '''compare if rule-specific variables are equal''' if not type(rule_obj) == RlimitRule: raise AppArmorBug('Passed non-rlimit rule: %s' % str(rule_obj)) if (self.rlimit != rule_obj.rlimit): return False if (self.value_as_int != rule_obj.value_as_int or self.all_values != rule_obj.all_values): return False return True def logprof_header_localvars(self): rlimit_txt = self.rlimit if self.all_values: values_txt = 'infinity' else: values_txt = self.value return [ _('Rlimit'), rlimit_txt, _('Value'), values_txt, ] class RlimitRuleset(BaseRuleset): '''Class to handle and store a collection of rlimit rules''' def get_glob(self, path_or_rule): '''Return the next possible glob. For rlimit rules, that can mean changing the value to 'infinity' ''' # XXX implement all options mentioned above ;-) raise AppArmorBug('get_glob() is not (yet) available for this rule type') def split_unit(value): matches = RE_NUMBER_UNIT.match(value) if not matches: raise AppArmorBug("Invalid value given to split_unit: %s" % value) number = int(matches.group('number')) unit = matches.group('unit') or '' return number, unit apparmor-2.13.3/utils/apparmor/rule/network.py0000644000175000017500000001723513502024172017210 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import re from apparmor.regex import RE_PROFILE_NETWORK from apparmor.common import AppArmorBug, AppArmorException, type_is_str from apparmor.rule import BaseRule, BaseRuleset, logprof_value_or_all, parse_modifiers # setup module translations from apparmor.translations import init_translation _ = init_translation() network_domain_keywords = [ 'unspec', 'unix', 'inet', 'ax25', 'ipx', 'appletalk', 'netrom', 'bridge', 'atmpvc', 'x25', 'inet6', 'rose', 'netbeui', 'security', 'key', 'netlink', 'packet', 'ash', 'econet', 'atmsvc', 'rds', 'sna', 'irda', 'pppox', 'wanpipe', 'llc', 'ib', 'mpls', 'can', 'tipc', 'bluetooth', 'iucv', 'rxrpc', 'isdn', 'phonet', 'ieee802154', 'caif', 'alg', 'nfc', 'vsock', 'kcm', 'qipcrtr', 'smc', 'xdp' ] network_type_keywords = ['stream', 'dgram', 'seqpacket', 'rdm', 'raw', 'packet'] network_protocol_keywords = ['tcp', 'udp', 'icmp'] RE_NETWORK_DOMAIN = '(' + '|'.join(network_domain_keywords) + ')' RE_NETWORK_TYPE = '(' + '|'.join(network_type_keywords) + ')' RE_NETWORK_PROTOCOL = '(' + '|'.join(network_protocol_keywords) + ')' RE_NETWORK_DETAILS = re.compile( '^\s*' + '(?P' + RE_NETWORK_DOMAIN + ')?' + # optional domain '(\s+(?P' + RE_NETWORK_TYPE + '|' + RE_NETWORK_PROTOCOL + '))?' + # optional type or protocol '\s*$') class NetworkRule(BaseRule): '''Class to handle and store a single network rule''' # Nothing external should reference this class, all external users # should reference the class field NetworkRule.ALL class __NetworkAll(object): pass ALL = __NetworkAll rule_name = 'network' def __init__(self, domain, type_or_protocol, audit=False, deny=False, allow_keyword=False, comment='', log_event=None): super(NetworkRule, self).__init__(audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, log_event=log_event) self.domain = None self.all_domains = False if domain == NetworkRule.ALL: self.all_domains = True elif type_is_str(domain): if domain in network_domain_keywords: self.domain = domain else: raise AppArmorBug('Passed unknown domain to NetworkRule: %s' % domain) else: raise AppArmorBug('Passed unknown object to NetworkRule: %s' % str(domain)) self.type_or_protocol = None self.all_type_or_protocols = False if type_or_protocol == NetworkRule.ALL: self.all_type_or_protocols = True elif type_is_str(type_or_protocol): if type_or_protocol in network_protocol_keywords: self.type_or_protocol = type_or_protocol elif type_or_protocol in network_type_keywords: self.type_or_protocol = type_or_protocol else: raise AppArmorBug('Passed unknown type_or_protocol to NetworkRule: %s' % type_or_protocol) else: raise AppArmorBug('Passed unknown object to NetworkRule: %s' % str(type_or_protocol)) @classmethod def _match(cls, raw_rule): return RE_PROFILE_NETWORK.search(raw_rule) @classmethod def _parse(cls, raw_rule): '''parse raw_rule and return NetworkRule''' matches = cls._match(raw_rule) if not matches: raise AppArmorException(_("Invalid network rule '%s'") % raw_rule) audit, deny, allow_keyword, comment = parse_modifiers(matches) rule_details = '' if matches.group('details'): rule_details = matches.group('details') if rule_details: details = RE_NETWORK_DETAILS.search(rule_details) if not details: raise AppArmorException(_("Invalid or unknown keywords in 'network %s" % rule_details)) if details.group('domain'): domain = details.group('domain') else: domain = NetworkRule.ALL if details.group('type_or_protocol'): type_or_protocol = details.group('type_or_protocol') else: type_or_protocol = NetworkRule.ALL else: domain = NetworkRule.ALL type_or_protocol = NetworkRule.ALL return NetworkRule(domain, type_or_protocol, audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment) def get_clean(self, depth=0): '''return rule (in clean/default formatting)''' space = ' ' * depth if self.all_domains: domain = '' elif self.domain: domain = ' %s' % self.domain else: raise AppArmorBug('Empty domain in network rule') if self.all_type_or_protocols: type_or_protocol = '' elif self.type_or_protocol: type_or_protocol = ' %s' % self.type_or_protocol else: raise AppArmorBug('Empty type or protocol in network rule') return('%s%snetwork%s%s,%s' % (space, self.modifiers_str(), domain, type_or_protocol, self.comment)) def is_covered_localvars(self, other_rule): '''check if other_rule is covered by this rule object''' if not self._is_covered_plain(self.domain, self.all_domains, other_rule.domain, other_rule.all_domains, 'domain'): return False if not self._is_covered_plain(self.type_or_protocol, self.all_type_or_protocols, other_rule.type_or_protocol, other_rule.all_type_or_protocols, 'type or protocol'): return False # still here? -> then it is covered return True def is_equal_localvars(self, rule_obj, strict): '''compare if rule-specific variables are equal''' if not type(rule_obj) == NetworkRule: raise AppArmorBug('Passed non-network rule: %s' % str(rule_obj)) if (self.domain != rule_obj.domain or self.all_domains != rule_obj.all_domains): return False if (self.type_or_protocol != rule_obj.type_or_protocol or self.all_type_or_protocols != rule_obj.all_type_or_protocols): return False return True def logprof_header_localvars(self): family = logprof_value_or_all(self.domain, self.all_domains) sock_type = logprof_value_or_all(self.type_or_protocol, self.all_type_or_protocols) return [ _('Network Family'), family, _('Socket Type'), sock_type, ] class NetworkRuleset(BaseRuleset): '''Class to handle and store a collection of network rules''' def get_glob(self, path_or_rule): '''Return the next possible glob. For network rules, that's "network DOMAIN," or "network," (all network)''' # XXX return 'network DOMAIN,' if 'network DOMAIN TYPE_OR_PROTOCOL' was given return 'network,' apparmor-2.13.3/utils/apparmor/rule/file.py0000644000175000017500000005214713502024172016437 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2016 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- from apparmor.aare import AARE from apparmor.regex import RE_PROFILE_FILE_ENTRY, strip_quotes from apparmor.common import AppArmorBug, AppArmorException, type_is_str from apparmor.rule import BaseRule, BaseRuleset, check_and_split_list, logprof_value_or_all, parse_modifiers, quote_if_needed # setup module translations from apparmor.translations import init_translation _ = init_translation() allow_exec_transitions = ('ix', 'ux', 'Ux', 'px', 'Px', 'cx', 'Cx') # 2 chars - len relevant for split_perms() allow_exec_fallback_transitions = ('pix', 'Pix', 'cix', 'Cix', 'pux', 'PUx', 'cux', 'CUx') # 3 chars - len relevant for split_perms() deny_exec_transitions = ('x') file_permissions = ('m', 'r', 'w', 'a', 'l', 'k') # also defines the write order class FileRule(BaseRule): '''Class to handle and store a single file rule''' # Nothing external should reference this class, all external users # should reference the class field FileRule.ALL class __FileAll(object): pass class __FileAnyExec(object): pass ALL = __FileAll ANY_EXEC = __FileAnyExec rule_name = 'file' def __init__(self, path, perms, exec_perms, target, owner, file_keyword=False, leading_perms=False, audit=False, deny=False, allow_keyword=False, comment='', log_event=None): '''Initialize FileRule Parameters: - path: string, AARE or FileRule.ALL - perms: string, set of chars or FileRule.ALL (must not contain exec mode) - exec_perms: None or string - target: string, AARE or FileRule.ALL - owner: bool - file_keyword: bool - leading_perms: bool ''' super(FileRule, self).__init__(audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, log_event=log_event) # rulepart partperms is_path log_event self.path, self.all_paths = self._aare_or_all(path, 'path', True, log_event) self.target, self.all_targets, = self._aare_or_all(target, 'target', False, log_event) self.can_glob = not self.all_paths self.can_glob_ext = not self.all_paths self.can_edit = not self.all_paths if type_is_str(perms): perms, tmp_exec_perms = split_perms(perms, deny) if tmp_exec_perms: raise AppArmorBug('perms must not contain exec perms') elif perms == None: perms = set() self.perms, self.all_perms, unknown_items = check_and_split_list(perms, file_permissions, FileRule.ALL, 'FileRule', 'permissions', allow_empty_list=True) if unknown_items: raise AppArmorBug('Passed unknown perms to FileRule: %s' % str(unknown_items)) if self.perms and 'a' in self.perms and 'w' in self.perms: raise AppArmorException("Conflicting permissions found: 'a' and 'w'") self.original_perms = None # might be set by aa-logprof / aa.py propose_file_rules() if exec_perms is None: self.exec_perms = None elif exec_perms == self.ANY_EXEC: self.exec_perms = exec_perms elif type_is_str(exec_perms): if deny: if exec_perms != 'x': raise AppArmorException(_("file deny rules only allow to use 'x' as execute mode, but not %s" % exec_perms)) else: if exec_perms == 'x': raise AppArmorException(_("Execute flag ('x') in file rule must specify the exec mode (ix, Px, Cx etc.)")) elif exec_perms not in allow_exec_transitions and exec_perms not in allow_exec_fallback_transitions: raise AppArmorBug('Unknown execute mode specified in file rule: %s' % exec_perms) self.exec_perms = exec_perms else: raise AppArmorBug('Passed unknown perms object to FileRule: %s' % str(perms)) if type(owner) is not bool: raise AppArmorBug('non-boolean value passed to owner flag') self.owner = owner self.can_owner = owner # offer '(O)wner permissions on/off' buttons only if the rule has the owner flag if type(file_keyword) is not bool: raise AppArmorBug('non-boolean value passed to file keyword flag') self.file_keyword = file_keyword if type(leading_perms) is not bool: raise AppArmorBug('non-boolean value passed to leading permissions flag') self.leading_perms = leading_perms # XXX subset # check for invalid combinations (bare 'file,' vs. path rule) # if (self.all_paths and not self.all_perms) or (not self.all_paths and self.all_perms): # raise AppArmorBug('all_paths and all_perms must be equal') # elif if self.all_paths and (self.exec_perms or self.target): raise AppArmorBug('exec perms or target specified for bare file rule') @classmethod def _match(cls, raw_rule): return RE_PROFILE_FILE_ENTRY.search(raw_rule) @classmethod def _parse(cls, raw_rule): '''parse raw_rule and return FileRule''' matches = cls._match(raw_rule) if not matches: raise AppArmorException(_("Invalid file rule '%s'") % raw_rule) audit, deny, allow_keyword, comment = parse_modifiers(matches) owner = bool(matches.group('owner')) leading_perms = False if matches.group('path'): path = strip_quotes(matches.group('path')) elif matches.group('path2'): path = strip_quotes(matches.group('path2')) leading_perms = True else: path = FileRule.ALL if matches.group('perms'): perms = matches.group('perms') perms, exec_perms = split_perms(perms, deny) elif matches.group('perms2'): perms = matches.group('perms2') perms, exec_perms = split_perms(perms, deny) leading_perms = True else: perms = FileRule.ALL exec_perms = None if matches.group('target'): target = strip_quotes(matches.group('target')) else: target = FileRule.ALL file_keyword = bool(matches.group('file_keyword')) return FileRule(path, perms, exec_perms, target, owner, file_keyword, leading_perms, audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment) def get_clean(self, depth=0): '''return rule (in clean/default formatting)''' space = ' ' * depth if self.all_paths: path = '' elif self.path: path = quote_if_needed(self.path.regex) else: raise AppArmorBug('Empty path in file rule') if self.all_perms: perms = '' else: perms = self._joint_perms() if not perms: raise AppArmorBug('Empty permissions in file rule') if self.leading_perms: path_and_perms = '%s %s' % (perms, path) else: path_and_perms = '%s %s' % (path, perms) if self.all_targets: target = '' elif self.target: target = ' -> %s' % quote_if_needed(self.target.regex) else: raise AppArmorBug('Empty exec target in file rule') if self.owner: owner = 'owner ' else: owner = '' if self.file_keyword: file_keyword = 'file ' else: file_keyword = '' if self.all_paths and self.all_perms and not path and not perms and not target: return('%s%s%sfile,%s' % (space, self.modifiers_str(), owner, self.comment)) # plain 'file,' rule elif not self.all_paths and not self.all_perms and path and perms: return('%s%s%s%s%s%s,%s' % (space, self.modifiers_str(), file_keyword, owner, path_and_perms, target, self.comment)) else: raise AppArmorBug('Invalid combination of path and perms in file rule - either specify path and perms, or none of them') def _joint_perms(self): '''return the permissions as string (using self.perms and self.exec_perms)''' return self._join_given_perms(self.perms, self.exec_perms) def _join_given_perms(self, perms, exec_perms): '''return the permissions as string (using the perms and exec_perms given as parameter)''' perm_string = '' for perm in file_permissions: if perm in perms: perm_string = perm_string + perm if exec_perms == self.ANY_EXEC: raise AppArmorBug("FileRule.ANY_EXEC can't be used for actual rules") if exec_perms: perm_string = perm_string + exec_perms return perm_string def is_covered_localvars(self, other_rule): '''check if other_rule is covered by this rule object''' if not self._is_covered_aare(self.path, self.all_paths, other_rule.path, other_rule.all_paths, 'path'): return False # perms can be empty if only exec_perms are specified, therefore disable the sanity check in _is_covered_list()... # 'w' covers 'a', therefore use perms_with_a() to temporarily add 'a' if 'w' is present if not self._is_covered_list(perms_with_a(self.perms), self.all_perms, perms_with_a(other_rule.perms), other_rule.all_perms, 'perms', sanity_check=False): return False # ... and do our own sanity check if not other_rule.perms and not other_rule.all_perms and not other_rule.exec_perms: raise AppArmorBug('No permission or exec permission specified in other file rule') if not self.exec_perms and other_rule.exec_perms: return False # TODO: handle fallback modes? if other_rule.exec_perms == self.ANY_EXEC and self.exec_perms: pass # other_rule has ANY_EXEC and self has an exec rule set -> covered, so avoid hitting the 'elif' branch elif other_rule.exec_perms and self.exec_perms != other_rule.exec_perms: return False # check exec_mode and target only if other_rule contains exec_perms (except ANY_EXEC) or link permissions # (for mrwk permissions, the target is ignored anyway) if (other_rule.exec_perms and other_rule.exec_perms != self.ANY_EXEC) or (other_rule.perms and 'l' in other_rule.perms): if not self._is_covered_aare(self.target, self.all_targets, other_rule.target, other_rule.all_targets, 'target'): return False # a different target means running with a different profile, therefore we have to be more strict than _is_covered_aare() # XXX should we enforce an exact match for a) exec and/or b) link target? if self.all_targets != other_rule.all_targets: return False if self.owner and not other_rule.owner: return False # no check for file_keyword and leading_perms - they are not relevant for is_covered() # still here? -> then it is covered return True def is_equal_localvars(self, rule_obj, strict): '''compare if rule-specific variables are equal''' if not type(rule_obj) == FileRule: raise AppArmorBug('Passed non-file rule: %s' % str(rule_obj)) if self.owner != rule_obj.owner: return False if not self._is_equal_aare(self.path, self.all_paths, rule_obj.path, rule_obj.all_paths, 'path'): return False if self.perms != rule_obj.perms: return False if self.all_perms != rule_obj.all_perms: return False if self.exec_perms != rule_obj.exec_perms: return False if not self._is_equal_aare(self.target, self.all_targets, rule_obj.target, rule_obj.all_targets, 'target'): return False if strict: # file_keyword and leading_perms are only cosmetics, but still a difference if self.file_keyword != rule_obj.file_keyword: return False if self.leading_perms != rule_obj.leading_perms: return False return True def severity(self, sev_db): if self.all_paths: severity = sev_db.rank_path('/**', 'mrwlkix') else: severity = -1 sev = sev_db.rank_path(self.path.regex, self._joint_perms()) if isinstance(sev, int): # type check avoids breakage caused by 'unknown' severity = max(severity, sev) if severity == -1: severity = sev # effectively 'unknown' return severity def logprof_header_localvars(self): headers = [] path = logprof_value_or_all(self.path, self.all_paths) headers += [_('Path'), path] old_mode = '' if self.original_perms: original_perms_all = self._join_given_perms(self.original_perms['allow']['all'], None) original_perms_owner = self._join_given_perms(self.original_perms['allow']['owner'] - self.original_perms['allow']['all'], None) # only list owner perms that are not covered by other perms if original_perms_all and original_perms_owner: old_mode = '%s + owner %s' % (original_perms_all, original_perms_owner) elif original_perms_all: old_mode = original_perms_all elif original_perms_owner: old_mode = 'owner %s' % original_perms_owner else: old_mode = '' if old_mode: headers += [_('Old Mode'), old_mode] perms = logprof_value_or_all(self.perms, self.all_perms) if self.perms or self.exec_perms: perms = self._joint_perms() if self.owner: perms = 'owner %s' % perms if not self.all_targets: perms = "%s -> %s" % (perms, self.target.regex) headers += [_('New Mode'), perms] # file_keyword and leading_perms are not really relevant return headers def glob(self): '''Change path to next possible glob''' if self.all_paths: return self.path = self.path.glob_path() self.raw_rule = None def glob_ext(self): '''Change path to next possible glob with extension''' if self.all_paths: return self.path = self.path.glob_path_withext() self.raw_rule = None def edit_header(self): if self.all_paths: raise AppArmorBug('Attemp to edit bare file rule') return(_('Enter new path: '), self.path.regex) def validate_edit(self, newpath): if self.all_paths: raise AppArmorBug('Attemp to edit bare file rule') newpath = AARE(newpath, True) # might raise AppArmorException if the new path doesn't start with / or a variable return newpath.match(self.path) def store_edit(self, newpath): if self.all_paths: raise AppArmorBug('Attemp to edit bare file rule') self.path = AARE(newpath, True) # might raise AppArmorException if the new path doesn't start with / or a variable self.raw_rule = None class FileRuleset(BaseRuleset): '''Class to handle and store a collection of file rules''' def get_rules_for_path(self, path, audit=False, deny=False): '''Get all rules matching the given path path can be str or AARE If audit is True, only return rules with the audit flag set. If deny is True, only return matching deny rules''' matching_rules = FileRuleset() for rule in self.rules: if (rule.all_paths or rule.path.match(path)) and ((not deny) or rule.deny) and ((not audit) or rule.audit): matching_rules.add(rule) return matching_rules def get_perms_for_path(self, path, audit=False, deny=False): '''Get the summarized permissions of all rules matching the given path, and the list of paths involved in the calculation path can be str or AARE If audit is True, only analyze rules with the audit flag set. If deny is True, only analyze matching deny rules Returns {'allow': {'owner': set_of_perms, 'all': set_of_perms}, 'deny': {'owner': set_of_perms, 'all': set_of_perms}, 'path': involved_paths} Note: exec rules and exec/link target are not honored! ''' # XXX do we need to honor the link target? perms = { 'allow': {'owner': set(), 'all': set() }, 'deny': {'owner': set(), 'all': set() }, } all_perms = { 'allow': {'owner': False, 'all': False }, 'deny': {'owner': False, 'all': False }, } paths = set() matching_rules = self.get_rules_for_path(path, audit, deny) for rule in matching_rules.rules: allow_or_deny = 'allow' if rule.deny: allow_or_deny = 'deny' owner_or_all = 'all' if rule.owner: owner_or_all = 'owner' if rule.all_perms: all_perms[allow_or_deny][owner_or_all] = True elif rule.perms: perms[allow_or_deny][owner_or_all] = perms[allow_or_deny][owner_or_all].union(rule.perms) paths.add(rule.path.regex) allow = {} deny = {} for who in ['all', 'owner']: if all_perms['allow'][who]: allow[who] = FileRule.ALL else: allow[who] = perms['allow'][who] if all_perms['deny'][who]: deny[who] = FileRule.ALL else: deny[who] = perms['deny'][who] return {'allow': allow, 'deny': deny, 'paths': paths} def get_exec_rules_for_path(self, path, only_exact_matches=True): '''Get all rules matching the given path that contain exec permissions path can be str or AARE''' matches = FileRuleset() for rule in self.get_rules_for_path(path).rules: if rule.exec_perms: if rule.path.is_equal(path): matches.add(rule) elif not only_exact_matches: matches.add(rule) return matches def get_exec_conflict_rules(self, oldrule): '''check if one of the exec rules conflict with oldrule. If yes, return the conflicting rules.''' conflictingrules = FileRuleset() if oldrule.exec_perms: execrules = self.get_exec_rules_for_path(oldrule.path) for mergerule in execrules.rules: if mergerule.exec_perms != oldrule.exec_perms or mergerule.target != oldrule.target: conflictingrules.add(mergerule) return conflictingrules def split_perms(perm_string, deny): '''parse permission string - perm_string: the permission string to parse - deny: True if this is a deny rule ''' perms = set() exec_mode = None while perm_string: if perm_string[0] in file_permissions: perms.add(perm_string[0]) perm_string = perm_string[1:] elif perm_string[0] == 'x': if not deny: raise AppArmorException(_("'x' must be preceded by an exec qualifier (i, P, C or U)")) exec_mode = 'x' perm_string = perm_string[1:] elif perm_string.startswith(allow_exec_transitions): if exec_mode and exec_mode != perm_string[0:2]: raise AppArmorException(_('conflicting execute permissions found: %s and %s' % (exec_mode, perm_string[0:2]))) exec_mode = perm_string[0:2] perm_string = perm_string[2:] elif perm_string.startswith(allow_exec_fallback_transitions): if exec_mode and exec_mode != perm_string[0:3]: raise AppArmorException(_('conflicting execute permissions found: %s and %s' % (exec_mode, perm_string[0:3]))) exec_mode = perm_string[0:3] perm_string = perm_string[3:] else: raise AppArmorException(_('permission contains unknown character(s) %s' % perm_string)) return perms, exec_mode def perms_with_a(perms): '''if perms includes 'w', add 'a' perms - perms: the original permissions ''' perms_with_a = set() if perms: perms_with_a = set(perms) if 'w' in perms_with_a: perms_with_a.add('a') return perms_with_a apparmor-2.13.3/utils/apparmor/rule/capability.py0000644000175000017500000001322313502024172017631 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2014 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import re from apparmor.regex import RE_PROFILE_CAP from apparmor.common import AppArmorBug, AppArmorException, type_is_str from apparmor.rule import BaseRule, BaseRuleset, logprof_value_or_all, parse_modifiers # setup module translations from apparmor.translations import init_translation _ = init_translation() class CapabilityRule(BaseRule): '''Class to handle and store a single capability rule''' # Nothing external should reference this class, all external users # should reference the class field CapabilityRule.ALL class __CapabilityAll(object): pass ALL = __CapabilityAll rule_name = 'capability' def __init__(self, cap_list, audit=False, deny=False, allow_keyword=False, comment='', log_event=None): super(CapabilityRule, self).__init__(audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment, log_event=log_event) # Because we support having multiple caps in one rule, # initializer needs to accept a list of caps. self.all_caps = False if cap_list == CapabilityRule.ALL: self.all_caps = True self.capability = set() else: if type_is_str(cap_list): self.capability = {cap_list} elif type(cap_list) == list and len(cap_list) > 0: self.capability = set(cap_list) else: raise AppArmorBug('Passed unknown object to CapabilityRule: %s' % str(cap_list)) # make sure none of the cap_list arguments are blank, in # case we decide to return one cap per output line for cap in self.capability: if len(cap.strip()) == 0: raise AppArmorBug('Passed empty capability to CapabilityRule: %s' % str(cap_list)) @classmethod def _match(cls, raw_rule): return RE_PROFILE_CAP.search(raw_rule) @classmethod def _parse(cls, raw_rule): '''parse raw_rule and return CapabilityRule''' matches = cls._match(raw_rule) if not matches: raise AppArmorException(_("Invalid capability rule '%s'") % raw_rule) audit, deny, allow_keyword, comment = parse_modifiers(matches) capability = [] if matches.group('capability'): capability = matches.group('capability').strip() capability = re.split("[ \t]+", capability) else: capability = CapabilityRule.ALL return CapabilityRule(capability, audit=audit, deny=deny, allow_keyword=allow_keyword, comment=comment) def get_clean(self, depth=0): '''return rule (in clean/default formatting)''' space = ' ' * depth if self.all_caps: return('%s%scapability,%s' % (space, self.modifiers_str(), self.comment)) else: caps = ' '.join(self.capability).strip() # XXX return multiple lines, one for each capability, instead? if caps: return('%s%scapability %s,%s' % (space, self.modifiers_str(), ' '.join(sorted(self.capability)), self.comment)) else: raise AppArmorBug("Empty capability rule") def is_covered_localvars(self, other_rule): '''check if other_rule is covered by this rule object''' if not self._is_covered_list(self.capability, self.all_caps, other_rule.capability, other_rule.all_caps, 'capability'): return False # still here? -> then it is covered return True def is_equal_localvars(self, rule_obj, strict): '''compare if rule-specific variables are equal''' if not type(rule_obj) == CapabilityRule: raise AppArmorBug('Passed non-capability rule: %s' % str(rule_obj)) if (self.capability != rule_obj.capability or self.all_caps != rule_obj.all_caps): return False return True def severity(self, sev_db): if self.all_caps: severity = sev_db.rank_capability('__ALL__') else: severity = -1 for cap in self.capability: sev = sev_db.rank_capability(cap) if isinstance(sev, int): # type check avoids breakage caused by 'unknown' severity = max(severity, sev) if severity == -1: severity = sev # effectively 'unknown' return severity def logprof_header_localvars(self): cap_txt = logprof_value_or_all(self.capability, self.all_caps) return [ _('Capability'), cap_txt, ] class CapabilityRuleset(BaseRuleset): '''Class to handle and store a collection of capability rules''' def get_glob(self, path_or_rule): '''Return the next possible glob. For capability rules, that's always "capability," (all capabilities)''' return 'capability,' apparmor-2.13.3/utils/pod2htmd.tmp0000644000175000017500000000000313502024375014606 0ustar jjjj . apparmor-2.13.3/utils/aa-notify.pod0000644000175000017500000000600413502024172014740 0ustar jjjj# This publication is intellectual property of Canonical Ltd. Its contents # can be duplicated, either in part or in whole, provided that a copyright # label is visibly located on each copy. # # All information found in this book has been compiled with utmost # attention to detail. However, this does not guarantee complete accuracy. # Neither Canonical Ltd, the authors, nor the translators shall be held # liable for possible errors or the consequences thereof. # # Many of the software and hardware descriptions cited in this book # are registered trademarks. All trade names are subject to copyright # restrictions and may be registered trade marks. Canonical Ltd # essentially adheres to the manufacturer's spelling. # # Names of products and trademarks appearing in this book (with or without # specific notation) are likewise subject to trademark and trade protection # laws and may thus fall under copyright restrictions. # =pod =head1 NAME aa-notify - display information about logged AppArmor messages. =head1 SYNOPSIS B [option] =head1 DESCRIPTION B will display a summary or provide desktop notifications for AppArmor DENIED messages. =head1 OPTIONS B accepts the following arguments: =over 4 =item -p, --poll poll AppArmor logs and display desktop notifications. Can be used with '-s' option to display a summary on startup. =item --display $DISPLAY set the DISPLAY environment variable to $DISPLAY (might be needed if sudo resets $DISPLAY) =item -f FILE, --file=FILE search FILE for AppArmor messages =item -l, --since-last show summary since last login. =item -s NUM, --since-days=NUM show summary for last NUM of days. =item -u USER, --user=USER user to drop privileges to when running privileged. When used with the -p option, this should be set to the user that will receive desktop notifications. This has no effect when running under sudo. =item -w NUM, --wait=NUM wait NUM seconds before displaying notifications (for use with -p) =item -v, --verbose show messages with summaries. =item -h, --help displays a short usage statement. =back =head1 CONFIGURATION System-wide configuration for B is done via /etc/apparmor/notify.conf: # set to 'yes' to enable AppArmor DENIED notifications show_notifications="yes" # only people in use_group can use aa-notify use_group="admin" # OPTIONAL - custom notification message body message_body="This is a custom notification message." # OPTIONAL - custom notification message footer message_footer="For more information visit https://foo.com" Per-user configuration is done via $XDG_CONFIG_HOME/apparmor/notify.conf (or the deprecated ~/.apparmor/notify.conf if it exists): # set to 'yes' to enable AppArmor DENIED notifications show_notifications="yes" =head1 BUGS B needs to be able to read the logfiles containing the AppArmor DENIED messages. If you find any additional bugs, please report them to Launchpad at L. =head1 SEE ALSO apparmor(7) =cut apparmor-2.13.3/utils/aa-notify.80000644000175000017500000001500313502024374014330 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "AA-NOTIFY 8" .TH AA-NOTIFY 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa\-notify \- display information about logged AppArmor messages. .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-notify\fR [option] .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBaa-notify\fR will display a summary or provide desktop notifications for AppArmor \s-1DENIED\s0 messages. .SH "OPTIONS" .IX Header "OPTIONS" \&\fBaa-notify\fR accepts the following arguments: .IP "\-p, \-\-poll" 4 .IX Item "-p, --poll" poll AppArmor logs and display desktop notifications. Can be used with '\-s' option to display a summary on startup. .ie n .IP "\-\-display $DISPLAY" 4 .el .IP "\-\-display \f(CW$DISPLAY\fR" 4 .IX Item "--display $DISPLAY" set the \s-1DISPLAY\s0 environment variable to \f(CW$DISPLAY\fR (might be needed if sudo resets \f(CW$DISPLAY\fR) .IP "\-f \s-1FILE,\s0 \-\-file=FILE" 4 .IX Item "-f FILE, --file=FILE" search \s-1FILE\s0 for AppArmor messages .IP "\-l, \-\-since\-last" 4 .IX Item "-l, --since-last" show summary since last login. .IP "\-s \s-1NUM,\s0 \-\-since\-days=NUM" 4 .IX Item "-s NUM, --since-days=NUM" show summary for last \s-1NUM\s0 of days. .IP "\-u \s-1USER,\s0 \-\-user=USER" 4 .IX Item "-u USER, --user=USER" user to drop privileges to when running privileged. When used with the \-p option, this should be set to the user that will receive desktop notifications. This has no effect when running under sudo. .IP "\-w \s-1NUM,\s0 \-\-wait=NUM" 4 .IX Item "-w NUM, --wait=NUM" wait \s-1NUM\s0 seconds before displaying notifications (for use with \-p) .IP "\-v, \-\-verbose" 4 .IX Item "-v, --verbose" show messages with summaries. .IP "\-h, \-\-help" 4 .IX Item "-h, --help" displays a short usage statement. .SH "CONFIGURATION" .IX Header "CONFIGURATION" System-wide configuration for \fBaa-notify\fR is done via /etc/apparmor/notify.conf: .PP .Vb 2 \& # set to \*(Aqyes\*(Aq to enable AppArmor DENIED notifications \& show_notifications="yes" \& \& # only people in use_group can use aa\-notify \& use_group="admin" \& \& # OPTIONAL \- custom notification message body \& message_body="This is a custom notification message." \& \& # OPTIONAL \- custom notification message footer \& message_footer="For more information visit https://foo.com" .Ve .PP Per-user configuration is done via \f(CW$XDG_CONFIG_HOME\fR/apparmor/notify.conf (or the deprecated ~/.apparmor/notify.conf if it exists): .PP .Vb 2 \& # set to \*(Aqyes\*(Aq to enable AppArmor DENIED notifications \& show_notifications="yes" .Ve .SH "BUGS" .IX Header "BUGS" \&\fBaa-notify\fR needs to be able to read the logfiles containing the AppArmor \s-1DENIED\s0 messages. .PP If you find any additional bugs, please report them to Launchpad at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7) apparmor-2.13.3/utils/severity.db0000644000175000017500000002454113502024172014534 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2002-2005 Novell/SUSE # Copyright (C) 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ # Allow this process to 0wn the machine: CAP_SYS_ADMIN 10 CAP_SYS_CHROOT 10 CAP_SYS_MODULE 10 CAP_SYS_PTRACE 10 CAP_SYS_RAWIO 10 CAP_MAC_ADMIN 10 CAP_MAC_OVERRIDE 10 # Allow other processes to 0wn the machine: CAP_SETPCAP 9 CAP_SETFCAP 9 CAP_CHOWN 9 CAP_FSETID 9 CAP_MKNOD 9 CAP_LINUX_IMMUTABLE 9 CAP_DAC_OVERRIDE 9 CAP_SETGID 9 CAP_SETUID 9 CAP_FOWNER 9 # Denial of service, bypass audit controls, information leak CAP_SYS_TIME 8 CAP_NET_ADMIN 8 CAP_SYS_RESOURCE 8 CAP_KILL 8 CAP_IPC_OWNER 8 CAP_SYS_PACCT 8 CAP_SYS_BOOT 8 CAP_NET_BIND_SERVICE 8 CAP_NET_RAW 8 CAP_SYS_NICE 8 CAP_LEASE 8 CAP_IPC_LOCK 8 CAP_SYS_TTY_CONFIG 8 CAP_AUDIT_CONTROL 8 CAP_AUDIT_WRITE 8 CAP_SYSLOG 8 CAP_WAKE_ALARM 8 CAP_BLOCK_SUSPEND 8 CAP_DAC_READ_SEARCH 7 CAP_AUDIT_READ 7 # unused CAP_NET_BROADCAST 0 # filename r w x # 'hard drives' are generally 4 10 0 /**/lost+found/** 5 5 0 /boot/** 7 10 0 /etc/passwd* 4 8 0 /etc/group* 4 8 0 /etc/shadow* 7 9 0 /etc/shadow* 7 9 0 /home/*/.ssh/** 7 9 0 /home/*/.gnupg/** 5 7 0 /home/** 4 6 0 /srv/** 4 6 0 /proc/** 6 9 0 /proc/sys/kernel/hotplug 2 10 0 /proc/sys/kernel/modprobe 2 10 0 /proc/kallsyms 7 0 0 /sys/** 4 8 0 /sys/power/state 2 8 0 /sys/firmware/** 2 10 0 /dev/pts/* 8 9 0 /dev/ptmx 8 9 0 /dev/pty* 8 9 0 /dev/null 0 0 0 /dev/adbmouse 3 8 0 /dev/ataraid 9 10 0 /dev/zero 0 0 0 /dev/agpgart* 8 10 0 /dev/aio 3 3 0 /dev/cbd/* 5 5 0 /dev/cciss/* 4 10 0 /dev/capi* 4 6 0 /dev/cfs0 4 10 0 /dev/compaq/* 4 10 0 /dev/cdouble* 4 8 0 /dev/cpu** 5 5 0 /dev/cpu**microcode 1 10 0 /dev/double* 4 8 0 /dev/hd* 4 10 0 /dev/sd* 4 10 0 /dev/ida/* 4 10 0 /dev/input/* 4 8 0 /dev/mapper/control 4 10 0 /dev/*mem 8 10 0 /dev/loop* 4 10 0 /dev/lp* 0 4 0 /dev/md* 4 10 0 /dev/msr 4 10 0 /dev/nb* 4 10 0 /dev/ram* 8 10 0 /dev/rd/* 4 10 0 /dev/*random 3 1 0 /dev/sbpcd* 4 0 0 /dev/rtc 6 0 0 /dev/sd* 4 10 0 /dev/sc* 4 10 0 /dev/sg* 4 10 0 /dev/st* 4 10 0 /dev/snd/* 3 8 0 /dev/usb/mouse* 4 6 0 /dev/usb/hid* 4 6 0 /dev/usb/tty* 4 6 0 /dev/tty* 8 9 0 /dev/stderr 0 0 0 /dev/stdin 0 0 0 /dev/stdout 0 0 0 /dev/ubd* 4 10 0 /dev/usbmouse* 4 6 0 /dev/userdma 8 10 0 /dev/vcs* 8 9 0 /dev/xta* 4 10 0 /dev/zero 0 0 0 /dev/inittcl 8 10 0 /dev/log 5 7 0 /etc/fstab 3 8 0 /etc/mtab 3 5 0 /etc/SuSEconfig/* 1 8 0 /etc/X11/* 2 7 0 /etc/X11/xinit/* 2 8 0 /etc/SuSE-release 1 5 0 /etc/issue* 1 3 0 /etc/motd 1 3 0 /etc/aliases.d/* 1 7 0 /etc/cron* 1 9 0 /etc/cups/* 2 7 0 /etc/default/* 3 8 0 /etc/init.d/* 1 10 0 /etc/permissions.d/* 1 8 0 /etc/ppp/* 2 6 0 /etc/ppp/*secrets 8 6 0 /etc/profile.d/* 1 8 0 /etc/skel/* 0 7 0 /etc/sysconfig/* 4 10 0 /etc/xinetd.d/* 1 9 0 /etc/termcap/* 1 4 0 /etc/ld.so.* 1 9 0 /etc/pam.d/* 3 9 0 /etc/udev/* 3 9 0 /etc/insserv.conf 3 6 0 /etc/security/* 1 9 0 /etc/securetty 0 7 0 /etc/sudoers 4 9 0 /etc/hotplug/* 2 10 0 /etc/xinitd.conf 1 9 0 /etc/gpm/* 2 10 0 /etc/ssl/** 2 7 0 /etc/shadow* 5 9 0 /etc/bash.bashrc 1 9 0 /etc/csh.cshrc 1 9 0 /etc/csh.login 1 9 0 /etc/inittab 1 10 0 /etc/profile* 1 9 0 /etc/shells 1 5 0 /etc/alternatives 1 6 0 /etc/sysctl.conf 3 7 0 /etc/dev.d/* 1 8 0 /etc/manpath.config 1 6 0 /etc/permissions* 1 8 0 /etc/evms.conf 3 8 0 /etc/exports 3 8 0 /etc/samba/* 5 8 0 /etc/ssh/* 3 8 0 /etc/ssh/ssh_host_*key 8 8 0 /etc/krb5.conf 4 8 0 /etc/ntp.conf 3 8 0 /etc/auto.* 3 8 0 /etc/postfix/* 3 7 0 /etc/postfix/*passwd* 6 7 0 /etc/postfix/*cert* 6 7 0 /etc/foomatic/* 3 5 0 /etc/printcap 3 5 0 /etc/youservers 4 9 0 /etc/grub.conf 7 10 0 /etc/modules.conf 4 10 0 /etc/resolv.conf 2 7 0 /etc/apache2/** 3 7 0 /etc/apache2/**ssl** 7 7 0 /etc/subdomain.d/** 6 10 0 /etc/apparmor.d/** 6 10 0 /etc/apparmor/** 6 10 0 /var/log/** 3 8 0 /var/adm/SuSEconfig/** 3 8 0 /var/adm/** 3 7 0 /var/lib/rpm/** 4 8 0 /var/run/nscd/* 3 3 0 /var/run/.nscd_socket 3 3 0 /usr/share/doc/** 1 1 0 /usr/share/man/** 3 5 0 /usr/X11/man/** 3 5 0 /usr/share/info/** 2 4 0 /usr/share/java/** 2 5 0 /usr/share/locale/** 2 4 0 /usr/share/sgml/** 2 4 0 /usr/share/YaST2/** 3 9 0 /usr/share/ghostscript/** 3 5 0 /usr/share/terminfo/** 1 8 0 /usr/share/latex2html/** 2 4 0 /usr/share/cups/** 5 6 0 /usr/share/susehelp/** 2 6 0 /usr/share/susehelp/cgi-bin/** 3 7 7 /usr/share/zoneinfo/** 2 7 0 /usr/share/zsh/** 3 6 0 /usr/share/vim/** 3 8 0 /usr/share/groff/** 3 7 0 /usr/share/vnc/** 3 8 0 /usr/share/wallpapers/** 2 4 0 /usr/X11** 3 8 5 /usr/X11*/bin/XFree86 3 8 8 /usr/X11*/bin/Xorg 3 8 8 /usr/X11*/bin/sux 3 8 8 /usr/X11*/bin/xconsole 3 7 7 /usr/X11*/bin/xhost 3 7 7 /usr/X11*/bin/xauth 3 7 7 /usr/X11*/bin/ethereal 3 6 8 /usr/lib/ooo-** 3 6 5 /usr/lib/lsb/** 2 8 8 /usr/lib/pt_chwon 2 8 5 /usr/lib/tcl** 2 5 3 /usr/lib/lib*so* 3 8 4 /usr/lib/iptables/* 2 8 2 /usr/lib/perl5/** 4 10 6 /usr/lib/*/perl/** 4 10 6 /usr/lib/*/perl5/** 4 10 6 /usr/lib/gconv/* 4 7 4 /usr/lib/locale/** 4 8 0 /usr/lib/jvm/** 5 7 5 /usr/lib/sasl*/** 5 8 4 /usr/lib/jvm-exports/** 5 7 5 /usr/lib/jvm-private/** 5 7 5 /usr/lib/python*/** 5 7 5 /usr/lib/libkrb5* 4 8 4 /usr/lib/postfix/* 4 7 4 /usr/lib/rpm/** 4 8 6 /usr/lib/rpm/gnupg/** 4 9 0 /usr/lib/apache2** 4 7 4 /usr/lib/mailman/** 4 6 4 /usr/bin/ldd 1 7 4 /usr/bin/netcat 5 7 8 /usr/bin/clear 2 6 3 /usr/bin/reset 2 6 3 /usr/bin/tput 2 6 3 /usr/bin/tset 2 6 3 /usr/bin/file 2 6 3 /usr/bin/ftp 3 7 5 /usr/bin/busybox 4 8 6 /usr/bin/rbash 4 8 5 /usr/bin/screen 3 6 5 /usr/bin/getfacl 3 7 4 /usr/bin/setfacl 3 7 9 /usr/bin/*awk* 3 7 7 /usr/bin/sudo 2 9 10 /usr/bin/lsattr 2 6 5 /usr/bin/chattr 2 7 8 /usr/bin/sed 3 7 6 /usr/bin/grep 2 7 2 /usr/bin/chroot 2 6 10 /usr/bin/dircolors 2 9 3 /usr/bin/cut 2 7 2 /usr/bin/du 2 7 3 /usr/bin/env 2 7 2 /usr/bin/head 2 7 2 /usr/bin/tail 2 7 2 /usr/bin/install 2 8 4 /usr/bin/link 2 6 4 /usr/bin/logname 2 6 2 /usr/bin/md5sum 2 8 3 /usr/bin/mkfifo 2 6 10 /usr/bin/nice 2 7 7 /usr/bin/nohup 2 7 7 /usr/bin/printf 2 7 1 /usr/bin/readlink 2 7 3 /usr/bin/seq 2 7 1 /usr/bin/sha1sum 2 8 3 /usr/bin/shred 2 7 3 /usr/bin/sort 2 7 3 /usr/bin/split 2 7 3 /usr/bin/stat 2 7 4 /usr/bin/sum 2 8 3 /usr/bin/tac 2 7 3 /usr/bin/tail 3 8 4 /usr/bin/tee 2 7 3 /usr/bin/test 2 8 4 /usr/bin/touch 2 7 3 /usr/bin/tr 2 8 3 /usr/bin/tsort 2 7 3 /usr/bin/tty 2 7 3 /usr/bin/unexpand 2 7 3 /usr/bin/uniq 2 7 3 /usr/bin/unlink 2 8 4 /usr/bin/uptime 2 7 3 /usr/bin/users 2 8 4 /usr/bin/vdir 2 8 4 /usr/bin/wc 2 7 3 /usr/bin/who 2 8 4 /usr/bin/whoami 2 8 4 /usr/bin/yes 1 6 1 /usr/bin/ed 2 7 5 /usr/bin/red 2 7 4 /usr/bin/find 2 8 5 /usr/bin/xargs 2 7 5 /usr/bin/ispell 2 7 4 /usr/bin/a2p 2 7 5 /usr/bin/perlcc 2 7 5 /usr/bin/perldoc 2 7 5 /usr/bin/pod2* 2 7 5 /usr/bin/prove 2 7 5 /usr/bin/perl 2 10 7 /usr/bin/perl* 2 10 7 /usr/bin/suidperl 2 8 8 /usr/bin/csh 2 8 8 /usr/bin/tcsh 2 8 8 /usr/bin/tree 2 6 5 /usr/bin/last 2 7 5 /usr/bin/lastb 2 7 5 /usr/bin/utmpdump 2 6 5 /usr/bin/alsamixer 2 6 8 /usr/bin/amixer 2 6 8 /usr/bin/amidi 2 6 8 /usr/bin/aoss 2 6 8 /usr/bin/aplay 2 6 8 /usr/bin/aplaymidi 2 6 8 /usr/bin/arecord 2 6 8 /usr/bin/arecordmidi 2 6 8 /usr/bin/aseqnet 2 6 8 /usr/bin/aserver 2 6 8 /usr/bin/iecset 2 6 8 /usr/bin/rview 2 6 5 /usr/bin/ex 2 7 5 /usr/bin/enscript 2 6 5 /usr/bin/genscript 2 6 5 /usr/bin/xdelta 2 6 5 /usr/bin/edit 2 6 5 /usr/bin/vimtutor 2 6 5 /usr/bin/rvim 2 6 5 /usr/bin/vim 2 8 7 /usr/bin/vimdiff 2 8 7 /usr/bin/aspell 2 6 5 /usr/bin/xxd 2 6 5 /usr/bin/spell 2 6 5 /usr/bin/eqn 2 6 5 /usr/bin/eqn2graph 2 6 5 /usr/bin/word-list-compress 2 6 4 /usr/bin/afmtodit 2 6 4 /usr/bin/hpf2dit 2 6 4 /usr/bin/geqn 2 6 4 /usr/bin/grn 2 6 4 /usr/bin/grodvi 2 6 4 /usr/bin/groff 2 6 5 /usr/bin/groffer 2 6 4 /usr/bin/grolj4 2 6 4 /usr/bin/grotty 2 6 4 /usr/bin/gtbl 2 6 4 /usr/bin/pic2graph 2 6 4 /usr/bin/indxbib 2 6 4 /usr/bin/lkbib 2 6 4 /usr/bin/lookbib 2 6 4 /usr/bin/mmroff 2 6 4 /usr/bin/neqn 2 6 4 /usr/bin/pfbtops 2 6 4 /usr/bin/pic 2 6 4 /usr/bin/tfmtodit 2 6 4 /usr/bin/tbl 2 6 4 /usr/bin/post-grohtml 2 6 4 /usr/bin/pre-grohtml 2 6 4 /usr/bin/refer 2 6 4 /usr/bin/soelim 2 6 4 /usr/bin/disable-paste 2 6 6 /usr/bin/troff 2 6 4 /usr/bin/strace-graph 2 6 4 /usr/bin/gpm-root 2 6 7 /usr/bin/hltest 2 6 7 /usr/bin/mev 2 6 6 /usr/bin/mouse-test 2 6 6 /usr/bin/strace 2 8 9 /usr/bin/scsiformat 2 7 10 /usr/bin/lsscsi 2 7 7 /usr/bin/scsiinfo 2 7 7 /usr/bin/sg_* 2 7 7 /usr/bin/build-classpath 2 6 6 /usr/bin/build-classpath-directory 2 6 6 /usr/bin/build-jar-repository 2 6 6 /usr/bin/diff-jars 2 6 6 /usr/bin/jvmjar 2 6 6 /usr/bin/rebuild-jar-repository 2 6 6 /usr/bin/scriptreplay 2 6 5 /usr/bin/cal 2 6 3 /usr/bin/chkdupexe 2 6 5 /usr/bin/col 2 6 4 /usr/bin/colcrt 2 6 4 /usr/bin/colrm 2 6 3 /usr/bin/column 2 6 4 /usr/bin/cytune 2 6 6 /usr/bin/ddate 2 6 3 /usr/bin/fdformat 2 6 6 /usr/bin/getopt 2 8 6 /usr/bin/hexdump 2 6 4 /usr/bin/hostid 2 6 4 /usr/bin/ipcrm 2 7 7 /usr/bin/ipcs 2 7 6 /usr/bin/isosize 2 6 4 /usr/bin/line 2 6 4 /usr/bin/look 2 6 5 /usr/bin/mcookie 2 7 5 /usr/bin/mesg 2 6 4 /usr/bin/namei 2 6 5 /usr/bin/rename 2 6 5 /usr/bin/renice 2 6 7 /usr/bin/rev 2 6 5 /usr/bin/script 2 6 6 /usr/bin/ChangeSymlinks 2 8 8 /usr/bin/setfdprm 2 6 7 /usr/bin/setsid 2 6 3 /usr/bin/setterm 2 6 5 /usr/bin/tailf 2 6 4 /usr/bin/time 2 6 4 /usr/bin/ul 2 6 4 /usr/bin/wall 2 6 5 /usr/bin/whereis 2 6 4 /usr/bin/which 2 6 3 /usr/bin/c_rehash 2 7 6 /usr/bin/openssl 2 8 6 /usr/bin/lsdev 2 6 5 /usr/bin/procinfo 2 6 5 /usr/bin/socklist 2 6 5 /usr/bin/filesize 2 6 3 /usr/bin/linkto 2 6 3 /usr/bin/mkinfodir 2 6 5 /usr/bin/old 2 6 4 /usr/bin/rpmlocate 2 6 5 /usr/bin/safe-rm 2 8 6 /usr/bin/safe-rmdir 2 8 6 /usr/bin/setJava 2 6 1 /usr/bin/vmstat 2 6 4 /usr/bin/top 2 6 6 /usr/bin/pinentry* 2 7 6 /usr/bin/free 2 8 4 /usr/bin/pmap 2 6 5 /usr/bin/slabtop 2 6 4 /usr/bin/tload 2 6 4 /usr/bin/watch 2 6 3 /usr/bin/w 2 6 4 /usr/bin/pstree.x11 2 6 4 /usr/bin/pstree 2 6 4 /usr/bin/snice 2 6 6 /usr/bin/skill 2 6 7 /usr/bin/pgrep 2 6 4 /usr/bin/killall 2 6 7 /usr/bin/curl 2 7 7 /usr/bin/slptool 2 7 8 /usr/bin/ldap* 2 7 7 /usr/bin/whatis 2 7 5 apparmor-2.13.3/utils/aa-easyprof.pod0000644000175000017500000002400613502024172015262 0ustar jjjj# This publication is intellectual property of Canonical Ltd. Its contents # can be duplicated, either in part or in whole, provided that a copyright # label is visibly located on each copy. # # All information found in this book has been compiled with utmost # attention to detail. However, this does not guarantee complete accuracy. # Neither Canonical Ltd, the authors, nor the translators shall be held # liable for possible errors or the consequences thereof. # # Many of the software and hardware descriptions cited in this book # are registered trademarks. All trade names are subject to copyright # restrictions and may be registered trade marks. Canonical Ltd # essentially adheres to the manufacturer's spelling. # # Names of products and trademarks appearing in this book (with or without # specific notation) are likewise subject to trademark and trade protection # laws and may thus fall under copyright restrictions. # =pod =head1 NAME aa-easyprof - AppArmor profile generation made easy. =head1 SYNOPSIS B [option] Epath to binaryE =head1 DESCRIPTION B provides an easy to use interface for AppArmor policy generation. B supports the use of templates and policy groups to quickly profile an application. Please note that while this tool can help with policy generation, its utility is dependent on the quality of the templates, policy groups and abstractions used. Also, this tool may create policy which is less restricted than creating policy by hand or with B and B. =head1 OPTIONS B accepts the following arguments: =over 4 =item -t TEMPLATE, --template=TEMPLATE Specify which template to use. May specify either a system template from /usr/share/apparmor/easyprof/templates or a filename for the template to use. If not specified, use /usr/share/apparmor/easyprof/templates/default. =item -p POLICYGROUPS, --policy-groups=POLICYGROUPS Specify POLICY as a comma-separated list of policy groups. See --list-templates for supported policy groups. The available policy groups are in /usr/share/apparmor/easyprof/policy. Policy groups are simply groupings of AppArmor rules or policies. They are similar to AppArmor abstractions, but usually encompass more policy rules. =item --parser PATH Specify the PATH of the apparmor_parser binary to use when verifying policy. If this option is not specified, aa-easyprof will attempt to locate the path starting with /sbin/apparmor_parser. =item -a ABSTRACTIONS, --abstractions=ABSTRACTIONS Specify ABSTRACTIONS as a comma-separated list of AppArmor abstractions. It is usually recommended you use policy groups instead, but this is provided as a convenience. AppArmor abstractions are located in /etc/apparmor.d/abstractions. See apparmor.d(5) for details. =item -b PATH, --base=PATH Set the base PATH for resolving abstractions specified by --abstractions. See the same option in apparmor_parser(8) for details. =item -I PATH, --Include=PATH Add PATH to the search paths used for resolving abstractions specified by --abstractions. See the same option in apparmor_parser(8) for details. =item -r PATH, --read-path=PATH Specify a PATH to allow owner reads. May be specified multiple times. If the PATH ends in a '/', then PATH is treated as a directory and reads are allowed to all files under this directory. Can optionally use '/*' at the end of the PATH to only allow reads to files directly in PATH. =item -w PATH, --write-dir=PATH Like --read-path but also allow owner writes in additions to reads. =item -n NAME, --name=NAME Specify NAME of policy. If not specified, NAME is set to the name of the binary. The NAME of the policy is typically only used for profile meta data and does not specify the AppArmor profile name. =item --profile-name=PROFILENAME Specify the AppArmor profile name. When set, uses 'profile PROFILENAME' in the profile. When set and specifying a binary, uses 'profile PROFILENAME BINARY' in the profile. If not set, the binary will be used as the profile name and profile attachment. =item --template-var="@{VAR}=VALUE" Set VAR to VALUE in the resulting policy. This typically only makes sense if the specified template uses this value. May be specified multiple times. =item --list-templates List available templates. =item --show-template Display template specified with --template. =item --templates-dir=PATH Use PATH instead of system templates directory. =item --include-templates-dir=PATH Include PATH when searching for templates in addition to the system templates directory (or the one specified with --templates-dir). System templates will match before those in PATH. =item --list-policy-groups List available policy groups. =item --show-policy-group Display policy groups specified with --policy-groups. =item --policy-groups-dir=PATH Use PATH instead of system policy-groups directory. =item --include-policy-groups-dir=PATH Include PATH when searching for policy groups in addition to the system policy-groups directory (or the one specified with --policy-groups-dir). System policy-groups will match before those in PATH. =item --policy-version=VERSION Must be used with --policy-vendor and is used to specify the version of policy groups and templates. When specified, B looks for the subdirectory VENDOR/VERSION within the policy-groups and templates directory. The specified version must be a positive decimal number compatible with the JSON Number type. Eg, when using: $ aa-easyprof --templates-dir=/usr/share/apparmor/easyprof/templates \ --policy-groups-dir=/usr/share/apparmor/easyprof/policygroups \ --policy-vendor="foo" \ --policy-version=1.0 Then /usr/share/apparmor/easyprof/templates/foo/1.0 will be searched for templates and /usr/share/apparmor/easyprof/policygroups/foo/1.0 for policy groups. =item --policy-vendor=VENDOR Must be used with --policy-version and is used to specify the vendor for policy groups and templates. See --policy-version for more information. =item --author Specify author of the policy. =item --copyright Specify copyright of the policy. =item --comment Specify comment for the policy. =item -m MANIFEST, --manifest=MANIFEST B also supports using a JSON manifest file for specifying options related to policy. Unlike command line arguments, the JSON file may specify multiple profiles. The structure of the JSON is: { "security": { "profiles": { "": { ... attributes specific to this profile ... }, "": { ... } } } } Each profile JSON object (ie, everything under a profile name) may specify any fields related to policy. The "security" JSON container object is optional and may be omitted. An example manifest file demonstrating all fields is: { "security": { "profiles": { "com.example.foo": { "abstractions": [ "audio", "gnome" ], "author": "Your Name", "binary": "/opt/foo/**", "comment": "Unstructured single-line comment", "copyright": "Unstructured single-line copyright statement", "name": "My Foo App", "policy_groups": [ "networking", "user-application" ], "policy_vendor": "somevendor", "policy_version": 1.0, "read_path": [ "/tmp/foo_r", "/tmp/bar_r/" ], "template": "user-application", "template_variables": { "APPNAME": "foo", "VAR1": "bar", "VAR2": "baz" }, "write_path": [ "/tmp/foo_w", "/tmp/bar_w/" ] } } } } A manifest file does not have to include all the fields. Eg, a manifest file for an Ubuntu SDK application might be: { "security": { "profiles": { "com.ubuntu.developer.myusername.MyCoolApp": { "policy_groups": [ "networking", "online-accounts" ], "policy_vendor": "ubuntu", "policy_version": 1.0, "template": "ubuntu-sdk", "template_variables": { "APPNAME": "MyCoolApp", "APPVERSION": "0.1.2" } } } } } =item --verify-manifest When used with --manifest, warn about potentially unsafe definitions in the manifest file. =item --output-format=FORMAT Specify either B (default if unspecified) for AppArmor policy output or B for JSON manifest format. =item --output-directory=DIR Specify output directory for profile. If unspecified, policy is sent to stdout. =back =head1 EXAMPLES Example usage for a program named 'foo' which is installed in /opt/foo: $ aa-easyprof --template=user-application --template-var="@{APPNAME}=foo" \ --policy-groups=opt-application,user-application \ /opt/foo/bin/FooApp When using a manifest file: $ aa-easyprof --manifest=manifest.json To output a manifest file based on aa-easyprof arguments: $ aa-easyprof --output-format=json \ --author="Your Name" \ --comment="Unstructured single-line comment" \ --copyright="Unstructured single-line copyright statement" \ --name="My Foo App" \ --profile-name="com.example.foo" \ --template="user-application" \ --policy-groups="user-application,networking" \ --abstractions="audio,gnome" \ --read-path="/tmp/foo_r" \ --read-path="/tmp/bar_r/" \ --write-path="/tmp/foo_w" \ --write-path=/tmp/bar_w/ \ --template-var="@{APPNAME}=foo" \ --template-var="@{VAR1}=bar" \ --template-var="@{VAR2}=baz" \ "/opt/foo/**" =head1 BUGS If you find any additional bugs, please report them to Launchpad at L. =head1 SEE ALSO apparmor(7) apparmor.d(5) =cut apparmor-2.13.3/utils/aa-unconfined.8.html0000644000175000017500000000610213502024376016115 0ustar jjjj
 

NAME

aa-unconfined - output a list of processes with tcp or udp ports that do not have AppArmor profiles loaded

SYNOPSIS

aa-unconfined [--paranoid] [--with-ss | --with-netstat]

OPTIONS

--paranoid

Displays all processes from /proc filesystem with tcp or udp ports that do not have AppArmor profiles loaded.

--with-ss

Use the ss(8) command to find processes listening on network sockets (the default).

--with-netstat

Use the netstat(8) command to find processes listening on network sockets. This is also what aa-unconfined will fall back to when ss(8) is not available.

DESCRIPTION

aa-unconfined will use netstat(8) to determine which processes have open network sockets and do not have AppArmor profiles loaded into the kernel.

BUGS

aa-unconfined must be run as root to retrieve the process executable link from the /proc filesystem. This program is susceptible to race conditions of several flavours: an unlinked executable will be mishandled; an executable started before an AppArmor profile is loaded will not appear in the output, despite running without confinement; a process that dies between the netstat(8) and further checks will be mishandled. This program only lists processes using TCP and UDP. In short, this program is unsuitable for forensics use and is provided only as an aid to profiling all network-accessible processes in the lab.

If you find any bugs, please report them at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

ss(8), netstat(8), apparmor(7), apparmor.d(5), aa_change_hat(2), and https://wiki.apparmor.net.

 
apparmor-2.13.3/utils/aa-mergeprof.pod0000644000175000017500000000135213502024172015417 0ustar jjjj=pod =head1 NAME aa-mergeprof - merge AppArmor security profiles. =head1 SYNOPSIS B [I ...] [I<-d /path/to/profiles>]> =head1 OPTIONS B One or more files containing profiles to merge into the profile directory (see -d). B<-d --dir /path/to/profiles> Specifies the target directory for the merged AppArmor security profile set. Defaults to /etc/apparmor.d. =head1 DESCRIPTION B =head1 BUGS If you find any bugs, please report them at L. =head1 SEE ALSO apparmor(7), apparmor.d(5), aa_change_hat(2), aa-genprof(1), aa-logprof(1), aa-enforce(1), aa-audit(1), aa-complain(1), aa-disable(1), and L. =cut apparmor-2.13.3/utils/aa-easyprof0000755000175000017500000001062413502024172014505 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2011-2015 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import apparmor.easyprof from apparmor.easyprof import error import os import sys # setup exception handling from apparmor.fail import enable_aa_exception_handler enable_aa_exception_handler() if __name__ == "__main__": def usage(): '''Return usage information''' return 'USAGE: %s [options] ' % \ os.path.basename(sys.argv[0]) (opt, args) = apparmor.easyprof.parse_args() binary = None manifest = None m = usage() if opt.show_policy_group and not opt.policy_groups: error("Must specify -p with --show-policy-group") elif not opt.template and not opt.policy_groups and len(args) < 1: error("Must specify full path to binary\n%s" % m) binary = None if len(args) >= 1: binary = args[0] # parse_manifest() returns a list of tuples (binary, options). Create a # list of these profile tuples to support multiple profiles in one manifest profiles = [] if opt.manifest: try: # should hide this in a common function if sys.version_info[0] >= 3: f = open(opt.manifest, "r", encoding="utf-8") else: f = open(opt.manifest, "r") manifest = f.read() except EnvironmentError as e: error("Could not read '%s': %s (%d)\n" % (opt.manifest, os.strerror(e.errno), e.errno)) profiles = apparmor.easyprof.parse_manifest(manifest, opt) else: # fake up a tuple list when processing command line args profiles.append( (binary, opt) ) count = 0 for (binary, options) in profiles: if len(profiles) > 1: count += 1 easyp = apparmor.easyprof.AppArmorEasyProfile(binary, options) if options.list_templates: apparmor.easyprof.print_basefilenames(easyp.get_templates()) sys.exit(0) elif options.template and options.show_template: sys_t = os.path.join(easyp.dirs['templates'], options.template) inc_t = None if options.include_templates_dir: inc_t = os.path.join(easyp.dirs['templates_include'], options.template) if os.path.exists(sys_t): apparmor.easyprof.print_files([sys_t]) elif os.path.exists(inc_t): apparmor.easyprof.print_files([inc_t]) else: error("Could not find '%s'" % options.template) sys.exit(0) elif options.list_policy_groups: apparmor.easyprof.print_basefilenames(easyp.get_policy_groups()) sys.exit(0) elif options.policy_groups and options.show_policy_group: files = [] for g in options.policy_groups.split(','): sys_g = os.path.join(easyp.dirs['policygroups'], g) inc_g = None if options.include_policy_groups_dir: inc_g = os.path.join(easyp.dirs['policygroups_include'], g) if os.path.exists(sys_g): files.append(sys_g) elif os.path.exists(inc_g): files.append(inc_g) else: error("Could not find '%s'" % g) apparmor.easyprof.print_files(files) sys.exit(0) elif binary == None and not options.profile_name and \ not options.manifest: error("Must specify binary and/or profile name\n%s" % m) params = apparmor.easyprof.gen_policy_params(binary, options) if options.manifest and options.verify_manifest and \ not apparmor.easyprof.verify_manifest(params): error("Manifest file requires review") if options.output_format == "json": sys.stdout.write('%s\n' % easyp.gen_manifest(params)) else: params['no_verify'] = options.no_verify easyp.output_policy(params, count, opt.output_directory) apparmor-2.13.3/utils/aa-remove-unknown.8.html0000644000175000017500000000453113502024376016763 0ustar jjjj
 

NAME

aa-remove-unknown - remove unknown AppArmor profiles

SYNOPSIS

aa-remove-unknown [option]

DESCRIPTION

aa-remove-unknown will inventory all profiles in /etc/apparmor.d/, compare that list to the profiles currently loaded into the kernel, and then remove all of the loaded profiles that were not found in /etc/apparmor.d/. It will also report the name of each profile that it removes on standard out.

OPTIONS

-h, --help

displays a short usage statement.

-n

dry run; only prints the names of profiles that would be removed

EXAMPLES

  $ sudo ./aa-remove-unknown -n
  Would remove 'test//null-/usr/bin/whoami'
  Would remove 'test'

  $ sudo ./aa-remove-unknown
  Removing 'test//null-/usr/bin/whoami'
  Removing 'test'

BUGS

None. Please report any you find to Launchpad at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7)

 
apparmor-2.13.3/utils/test/0000755000175000017500000000000013502024172013324 5ustar jjjjapparmor-2.13.3/utils/test/easyprof.conf0000644000175000017500000000020013502024172016013 0ustar jjjj# Location of system policygroups POLICYGROUPS_DIR="./policygroups" # Location of system templates TEMPLATES_DIR="./templates" apparmor-2.13.3/utils/test/test-network.py0000644000175000017500000005322413502024172016352 0ustar jjjj#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import unittest from collections import namedtuple from common_test import AATest, setup_all_loops from apparmor.rule.network import NetworkRule, NetworkRuleset, network_domain_keywords from apparmor.rule import BaseRule from apparmor.common import AppArmorException, AppArmorBug, cmd from apparmor.logparser import ReadLog from apparmor.translations import init_translation _ = init_translation() exp = namedtuple('exp', ['audit', 'allow_keyword', 'deny', 'comment', 'domain', 'all_domains', 'type_or_protocol', 'all_type_or_protocols']) # --- check if the keyword list is up to date --- # class NetworkKeywordsTest(AATest): def test_network_keyword_list(self): rc, output = cmd(['make', '-s', '--no-print-directory', 'list_af_names']) self.assertEqual(rc, 0) af_names = [] af_pairs = output.replace('AF_', '').strip().lower().split(",") for af_pair in af_pairs: af_name = af_pair.lstrip().split(" ")[0] # skip max af name definition if len(af_name) > 0 and af_name != "max": af_names.append(af_name) missing_af_names = [] for keyword in af_names: if keyword not in network_domain_keywords: # keywords missing in the system are ok (= older kernel), but network_domain_keywords needs to have the full list missing_af_names.append(keyword) self.assertEqual(missing_af_names, [], 'Missing af_names in NetworkRule network_domain_keywords. This test is likely running ' 'on an newer kernel and will require updating the list of network domain keywords in utils/apparmor/rule/network.py') # --- tests for single NetworkRule --- # class NetworkTest(AATest): def _compare_obj(self, obj, expected): self.assertEqual(expected.allow_keyword, obj.allow_keyword) self.assertEqual(expected.audit, obj.audit) self.assertEqual(expected.domain, obj.domain) self.assertEqual(expected.type_or_protocol, obj.type_or_protocol) self.assertEqual(expected.all_domains, obj.all_domains) self.assertEqual(expected.all_type_or_protocols, obj.all_type_or_protocols) self.assertEqual(expected.deny, obj.deny) self.assertEqual(expected.comment, obj.comment) class NetworkTestParse(NetworkTest): tests = [ # rawrule audit allow deny comment domain all? type/proto all? ('network,' , exp(False, False, False, '' , None , True , None , True )), ('network inet,' , exp(False, False, False, '' , 'inet', False, None , True )), ('network inet stream,' , exp(False, False, False, '' , 'inet', False, 'stream' , False)), ('deny network inet stream, # comment' , exp(False, False, True , ' # comment' , 'inet', False, 'stream' , False)), ('audit allow network tcp,' , exp(True , True , False, '' , None , True , 'tcp' , False)), ('network stream,' , exp(False, False, False, '' , None , True , 'stream' , False)), ] def _run_test(self, rawrule, expected): self.assertTrue(NetworkRule.match(rawrule)) obj = NetworkRule.parse(rawrule) self.assertEqual(rawrule.strip(), obj.raw_rule) self._compare_obj(obj, expected) class NetworkTestParseInvalid(NetworkTest): tests = [ ('network foo,' , AppArmorException), ('network foo bar,' , AppArmorException), ('network foo tcp,' , AppArmorException), ('network inet bar,' , AppArmorException), ] def _run_test(self, rawrule, expected): self.assertTrue(NetworkRule.match(rawrule)) # the above invalid rules still match the main regex! with self.assertRaises(expected): NetworkRule.parse(rawrule) class NetworkTestParseFromLog(NetworkTest): def test_net_from_log(self): parser = ReadLog('', '', '', '') event = 'type=AVC msg=audit(1428699242.551:386): apparmor="DENIED" operation="create" profile="/bin/ping" pid=10589 comm="ping" family="inet" sock_type="raw" protocol=1' parsed_event = parser.parse_event(event) self.assertEqual(parsed_event, { 'request_mask': None, 'denied_mask': None, 'error_code': 0, 'family': 'inet', 'magic_token': 0, 'parent': 0, 'profile': '/bin/ping', 'protocol': 'icmp', 'sock_type': 'raw', 'operation': 'create', 'resource': None, 'info': None, 'aamode': 'REJECTING', 'time': 1428699242, 'active_hat': None, 'pid': 10589, 'task': 0, 'attr': None, 'name2': None, 'name': None, }) obj = NetworkRule(parsed_event['family'], parsed_event['sock_type'], log_event=parsed_event) # audit allow deny comment domain all? type/proto all? expected = exp(False, False, False, '' , 'inet', False, 'raw' , False) self._compare_obj(obj, expected) self.assertEqual(obj.get_raw(1), ' network inet raw,') class NetworkFromInit(NetworkTest): tests = [ # NetworkRule object audit allow deny comment domain all? type/proto all? (NetworkRule('inet', 'raw', deny=True) , exp(False, False, True , '' , 'inet', False, 'raw' , False)), (NetworkRule('inet', 'raw') , exp(False, False, False, '' , 'inet', False, 'raw' , False)), (NetworkRule('inet', NetworkRule.ALL) , exp(False, False, False, '' , 'inet', False, None , True )), (NetworkRule(NetworkRule.ALL, NetworkRule.ALL) , exp(False, False, False, '' , None , True , None , True )), (NetworkRule(NetworkRule.ALL, 'tcp') , exp(False, False, False, '' , None , True , 'tcp' , False)), (NetworkRule(NetworkRule.ALL, 'stream') , exp(False, False, False, '' , None , True , 'stream' , False)), ] def _run_test(self, obj, expected): self._compare_obj(obj, expected) class InvalidNetworkInit(AATest): tests = [ # init params expected exception (['inet', '' ] , AppArmorBug), # empty type_or_protocol (['' , 'tcp' ] , AppArmorBug), # empty domain ([' ', 'tcp' ] , AppArmorBug), # whitespace domain (['inet', ' ' ] , AppArmorBug), # whitespace type_or_protocol (['xyxy', 'tcp' ] , AppArmorBug), # invalid domain (['inet', 'xyxy' ] , AppArmorBug), # invalid type_or_protocol ([dict(), 'tcp' ] , AppArmorBug), # wrong type for domain ([None , 'tcp' ] , AppArmorBug), # wrong type for domain (['inet', dict() ] , AppArmorBug), # wrong type for type_or_protocol (['inet', None ] , AppArmorBug), # wrong type for type_or_protocol ] def _run_test(self, params, expected): with self.assertRaises(expected): NetworkRule(params[0], params[1]) def test_missing_params_1(self): with self.assertRaises(TypeError): NetworkRule() def test_missing_params_2(self): with self.assertRaises(TypeError): NetworkRule('inet') class InvalidNetworkTest(AATest): def _check_invalid_rawrule(self, rawrule): obj = None self.assertFalse(NetworkRule.match(rawrule)) with self.assertRaises(AppArmorException): obj = NetworkRule(NetworkRule.parse(rawrule)) self.assertIsNone(obj, 'NetworkRule handed back an object unexpectedly') def test_invalid_net_missing_comma(self): self._check_invalid_rawrule('network') # missing comma def test_invalid_net_non_NetworkRule(self): self._check_invalid_rawrule('dbus,') # not a network rule def test_empty_net_data_1(self): obj = NetworkRule('inet', 'stream') obj.domain = '' # no domain set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) def test_empty_net_data_2(self): obj = NetworkRule('inet', 'stream') obj.type_or_protocol = '' # no type_or_protocol set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) class WriteNetworkTestAATest(AATest): def _run_test(self, rawrule, expected): self.assertTrue(NetworkRule.match(rawrule)) obj = NetworkRule.parse(rawrule) clean = obj.get_clean() raw = obj.get_raw() self.assertEqual(expected.strip(), clean, 'unexpected clean rule') self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule') tests = [ # raw rule clean rule (' network , # foo ' , 'network, # foo'), (' audit network inet,' , 'audit network inet,'), (' deny network inet stream,# foo bar' , 'deny network inet stream, # foo bar'), (' deny network inet ,# foo bar' , 'deny network inet, # foo bar'), (' allow network tcp ,# foo bar' , 'allow network tcp, # foo bar'), ] def test_write_manually(self): obj = NetworkRule('inet', 'stream', allow_keyword=True) expected = ' allow network inet stream,' self.assertEqual(expected, obj.get_clean(2), 'unexpected clean rule') self.assertEqual(expected, obj.get_raw(2), 'unexpected raw rule') class NetworkCoveredTest(AATest): def _run_test(self, param, expected): obj = NetworkRule.parse(self.rule) check_obj = NetworkRule.parse(param) self.assertTrue(NetworkRule.match(param)) self.assertEqual(obj.is_equal(check_obj), expected[0], 'Mismatch in is_equal, expected %s' % expected[0]) self.assertEqual(obj.is_equal(check_obj, True), expected[1], 'Mismatch in is_equal/strict, expected %s' % expected[1]) self.assertEqual(obj.is_covered(check_obj), expected[2], 'Mismatch in is_covered, expected %s' % expected[2]) self.assertEqual(obj.is_covered(check_obj, True, True), expected[3], 'Mismatch in is_covered/exact, expected %s' % expected[3]) class NetworkCoveredTest_01(NetworkCoveredTest): rule = 'network inet,' tests = [ # rule equal strict equal covered covered exact ('network,' , [ False , False , False , False ]), ('network inet,' , [ True , True , True , True ]), ('network inet, # comment' , [ True , False , True , True ]), ('allow network inet,' , [ True , False , True , True ]), ('network inet,' , [ True , False , True , True ]), ('network inet stream,' , [ False , False , True , True ]), ('network inet tcp,' , [ False , False , True , True ]), ('audit network inet,' , [ False , False , False , False ]), ('audit network,' , [ False , False , False , False ]), ('network unix,' , [ False , False , False , False ]), ('network tcp,' , [ False , False , False , False ]), ('audit deny network inet,' , [ False , False , False , False ]), ('deny network inet,' , [ False , False , False , False ]), ] class NetworkCoveredTest_02(NetworkCoveredTest): rule = 'audit network inet,' tests = [ # rule equal strict equal covered covered exact ( 'network inet,' , [ False , False , True , False ]), ('audit network inet,' , [ True , True , True , True ]), ( 'network inet stream,' , [ False , False , True , False ]), ('audit network inet stream,' , [ False , False , True , True ]), ( 'network,' , [ False , False , False , False ]), ('audit network,' , [ False , False , False , False ]), ('network unix,' , [ False , False , False , False ]), ] class NetworkCoveredTest_03(NetworkCoveredTest): rule = 'network inet stream,' tests = [ # rule equal strict equal covered covered exact ( 'network inet stream,' , [ True , True , True , True ]), ('allow network inet stream,' , [ True , False , True , True ]), ( 'network inet,' , [ False , False , False , False ]), ( 'network,' , [ False , False , False , False ]), ( 'network inet tcp,' , [ False , False , False , False ]), ('audit network,' , [ False , False , False , False ]), ('audit network inet stream,' , [ False , False , False , False ]), ( 'network unix,' , [ False , False , False , False ]), ( 'network,' , [ False , False , False , False ]), ] class NetworkCoveredTest_04(NetworkCoveredTest): rule = 'network,' tests = [ # rule equal strict equal covered covered exact ( 'network,' , [ True , True , True , True ]), ('allow network,' , [ True , False , True , True ]), ( 'network inet,' , [ False , False , True , True ]), ( 'network inet6 stream,' , [ False , False , True , True ]), ( 'network tcp,' , [ False , False , True , True ]), ( 'network inet raw,' , [ False , False , True , True ]), ('audit network,' , [ False , False , False , False ]), ('deny network,' , [ False , False , False , False ]), ] class NetworkCoveredTest_05(NetworkCoveredTest): rule = 'deny network inet,' tests = [ # rule equal strict equal covered covered exact ( 'deny network inet,' , [ True , True , True , True ]), ('audit deny network inet,' , [ False , False , False , False ]), ( 'network inet,' , [ False , False , False , False ]), # XXX should covered be true here? ( 'deny network unix,' , [ False , False , False , False ]), ( 'deny network,' , [ False , False , False , False ]), ] class NetworkCoveredTest_Invalid(AATest): def test_borked_obj_is_covered_1(self): obj = NetworkRule.parse('network inet,') testobj = NetworkRule('inet', 'stream') testobj.domain = '' with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_borked_obj_is_covered_2(self): obj = NetworkRule.parse('network inet,') testobj = NetworkRule('inet', 'stream') testobj.type_or_protocol = '' with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_invalid_is_covered(self): obj = NetworkRule.parse('network inet,') testobj = BaseRule() # different type with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_invalid_is_equal(self): obj = NetworkRule.parse('network inet,') testobj = BaseRule() # different type with self.assertRaises(AppArmorBug): obj.is_equal(testobj) class NetworkLogprofHeaderTest(AATest): tests = [ ('network,', [ _('Network Family'), _('ALL'), _('Socket Type'), _('ALL'), ]), ('network inet,', [ _('Network Family'), 'inet', _('Socket Type'), _('ALL'), ]), ('network inet stream,', [ _('Network Family'), 'inet', _('Socket Type'), 'stream', ]), ('deny network,', [_('Qualifier'), 'deny', _('Network Family'), _('ALL'), _('Socket Type'), _('ALL'), ]), ('allow network inet,', [_('Qualifier'), 'allow', _('Network Family'), 'inet', _('Socket Type'), _('ALL'), ]), ('audit network inet stream,', [_('Qualifier'), 'audit', _('Network Family'), 'inet', _('Socket Type'), 'stream', ]), ('audit deny network inet,', [_('Qualifier'), 'audit deny', _('Network Family'), 'inet', _('Socket Type'), _('ALL'), ]), ] def _run_test(self, params, expected): obj = NetworkRule._parse(params) self.assertEqual(obj.logprof_header(), expected) class NetworkRuleReprTest(AATest): tests = [ (NetworkRule('inet', 'stream'), ' network inet stream,'), (NetworkRule.parse(' allow network inet stream, # foo'), ' allow network inet stream, # foo'), ] def _run_test(self, params, expected): self.assertEqual(str(params), expected) ## --- tests for NetworkRuleset --- # class NetworkRulesTest(AATest): def test_empty_ruleset(self): ruleset = NetworkRuleset() ruleset_2 = NetworkRuleset() self.assertEqual([], ruleset.get_raw(2)) self.assertEqual([], ruleset.get_clean(2)) self.assertEqual([], ruleset_2.get_raw(2)) self.assertEqual([], ruleset_2.get_clean(2)) def test_ruleset_1(self): ruleset = NetworkRuleset() rules = [ 'network tcp,', 'network inet,', ] expected_raw = [ 'network tcp,', 'network inet,', '', ] expected_clean = [ 'network inet,', 'network tcp,', '', ] for rule in rules: ruleset.add(NetworkRule.parse(rule)) self.assertEqual(expected_raw, ruleset.get_raw()) self.assertEqual(expected_clean, ruleset.get_clean()) def test_ruleset_2(self): ruleset = NetworkRuleset() rules = [ 'network inet6 raw,', 'allow network inet,', 'deny network udp, # example comment', ] expected_raw = [ ' network inet6 raw,', ' allow network inet,', ' deny network udp, # example comment', '', ] expected_clean = [ ' deny network udp, # example comment', '', ' allow network inet,', ' network inet6 raw,', '', ] for rule in rules: ruleset.add(NetworkRule.parse(rule)) self.assertEqual(expected_raw, ruleset.get_raw(1)) self.assertEqual(expected_clean, ruleset.get_clean(1)) class NetworkGlobTestAATest(AATest): def setUp(self): self.maxDiff = None self.ruleset = NetworkRuleset() def test_glob_1(self): self.assertEqual(self.ruleset.get_glob('network inet,'), 'network,') # not supported or used yet # def test_glob_2(self): # self.assertEqual(self.ruleset.get_glob('network inet raw,'), 'network inet,') def test_glob_ext(self): with self.assertRaises(NotImplementedError): # get_glob_ext is not available for network rules self.ruleset.get_glob_ext('network inet raw,') class NetworkDeleteTestAATest(AATest): pass class NetworkRulesetReprTest(AATest): def test_network_ruleset_repr(self): obj = NetworkRuleset() obj.add(NetworkRule('inet', 'stream')) obj.add(NetworkRule.parse(' allow network inet stream, # foo')) expected = '\n network inet stream,\n allow network inet stream, # foo\n' self.assertEqual(str(obj), expected) setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-change_profile.py0000644000175000017500000006444013502024172017630 0ustar jjjj#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import unittest from collections import namedtuple from common_test import AATest, setup_all_loops from apparmor.rule.change_profile import ChangeProfileRule, ChangeProfileRuleset from apparmor.rule import BaseRule from apparmor.common import AppArmorException, AppArmorBug from apparmor.logparser import ReadLog from apparmor.translations import init_translation _ = init_translation() exp = namedtuple('exp', ['audit', 'allow_keyword', 'deny', 'comment', 'execmode', 'execcond', 'all_execconds', 'targetprofile', 'all_targetprofiles']) # --- tests for single ChangeProfileRule --- # class ChangeProfileTest(AATest): def _compare_obj(self, obj, expected): self.assertEqual(expected.allow_keyword, obj.allow_keyword) self.assertEqual(expected.audit, obj.audit) self.assertEqual(expected.execmode, obj.execmode) self.assertEqual(expected.execcond, obj.execcond) self.assertEqual(expected.targetprofile, obj.targetprofile) self.assertEqual(expected.all_execconds, obj.all_execconds) self.assertEqual(expected.all_targetprofiles, obj.all_targetprofiles) self.assertEqual(expected.deny, obj.deny) self.assertEqual(expected.comment, obj.comment) class ChangeProfileTestParse(ChangeProfileTest): tests = [ # rawrule audit allow deny comment execmode execcond all? targetprof all? ('change_profile,' , exp(False, False, False, '' , None , None , True , None , True )), ('change_profile /foo,' , exp(False, False, False, '' , None , '/foo', False, None , True )), ('change_profile safe /foo,' , exp(False, False, False, '' , 'safe' , '/foo', False, None , True )), ('change_profile unsafe /foo,' , exp(False, False, False, '' , 'unsafe' , '/foo', False, None , True )), ('change_profile /foo -> /bar,' , exp(False, False, False, '' , None , '/foo', False, '/bar' , False)), ('change_profile safe /foo -> /bar,' , exp(False, False, False, '' , 'safe' , '/foo', False, '/bar' , False)), ('change_profile unsafe /foo -> /bar,' , exp(False, False, False, '' , 'unsafe' , '/foo', False, '/bar' , False)), ('deny change_profile /foo -> /bar, # comment' , exp(False, False, True , ' # comment' , None , '/foo', False, '/bar' , False)), ('audit allow change_profile safe /foo,' , exp(True , True , False, '' , 'safe' , '/foo', False, None , True )), ('change_profile -> /bar,' , exp(False, False, False, '' , None , None , True , '/bar' , False)), ('audit allow change_profile -> /bar,' , exp(True , True , False, '' , None , None , True , '/bar' , False)), # quoted versions ('change_profile "/foo",' , exp(False, False, False, '' , None , '/foo', False, None , True )), ('change_profile "/foo" -> "/bar",' , exp(False, False, False, '' , None , '/foo', False, '/bar' , False)), ('deny change_profile "/foo" -> "/bar", # cmt' , exp(False, False, True, ' # cmt' , None , '/foo', False, '/bar' , False)), ('audit allow change_profile "/foo",' , exp(True , True , False, '' , None , '/foo', False, None , True )), ('change_profile -> "/bar",' , exp(False, False, False, '' , None , None , True , '/bar' , False)), ('audit allow change_profile -> "/bar",' , exp(True , True , False, '' , None , None , True , '/bar' , False)), # with globbing and/or named profiles ('change_profile,' , exp(False, False, False, '' , None , None , True , None , True )), ('change_profile /*,' , exp(False, False, False, '' , None , '/*' , False, None , True )), ('change_profile /* -> bar,' , exp(False, False, False, '' , None , '/*' , False, 'bar' , False)), ('deny change_profile /** -> bar, # comment' , exp(False, False, True , ' # comment' , None , '/**' , False, 'bar' , False)), ('audit allow change_profile /**,' , exp(True , True , False, '' , None , '/**' , False, None , True )), ('change_profile -> "ba r",' , exp(False, False, False, '' , None , None , True , 'ba r' , False)), ('audit allow change_profile -> "ba r",' , exp(True , True , False, '' , None , None , True , 'ba r' , False)), ] def _run_test(self, rawrule, expected): self.assertTrue(ChangeProfileRule.match(rawrule)) obj = ChangeProfileRule.parse(rawrule) self.assertEqual(rawrule.strip(), obj.raw_rule) self._compare_obj(obj, expected) class ChangeProfileTestParseInvalid(ChangeProfileTest): tests = [ ('change_profile -> ,' , AppArmorException), ('change_profile foo -> ,' , AppArmorException), ('change_profile notsafe,' , AppArmorException), ('change_profile safety -> /bar,' , AppArmorException), ] def _run_test(self, rawrule, expected): self.assertFalse(ChangeProfileRule.match(rawrule)) with self.assertRaises(expected): ChangeProfileRule.parse(rawrule) class ChangeProfileTestParseFromLog(ChangeProfileTest): def test_change_profile_from_log(self): parser = ReadLog('', '', '', '') event = 'type=AVC msg=audit(1428699242.551:386): apparmor="DENIED" operation="change_profile" profile="/foo/changeprofile" pid=3459 comm="changeprofile" target="/foo/rename"' # libapparmor doesn't understand this log format (from JJ) # event = '[ 97.492562] audit: type=1400 audit(1431116353.523:77): apparmor="DENIED" operation="change_profile" profile="/foo/changeprofile" pid=3459 comm="changeprofile" target="/foo/rename"' parsed_event = parser.parse_event(event) self.assertEqual(parsed_event, { 'request_mask': None, 'denied_mask': None, 'error_code': 0, 'magic_token': 0, 'parent': 0, 'profile': '/foo/changeprofile', 'operation': 'change_profile', 'resource': None, 'info': None, 'aamode': 'REJECTING', 'time': 1428699242, 'active_hat': None, 'pid': 3459, 'task': 0, 'attr': None, 'name2': '/foo/rename', # target 'name': None, 'family': None, 'protocol': None, 'sock_type': None, }) obj = ChangeProfileRule(None, ChangeProfileRule.ALL, parsed_event['name2'], log_event=parsed_event) # audit allow deny comment execmode execcond all? targetprof all? expected = exp(False, False, False, '' , None, None, True, '/foo/rename', False) self._compare_obj(obj, expected) self.assertEqual(obj.get_raw(1), ' change_profile -> /foo/rename,') class ChangeProfileFromInit(ChangeProfileTest): tests = [ # ChangeProfileRule object audit allow deny comment execmode execcond all? targetprof all? (ChangeProfileRule(None , '/foo', '/bar', deny=True) , exp(False, False, True , '' , None , '/foo', False, '/bar' , False)), (ChangeProfileRule(None , '/foo', '/bar') , exp(False, False, False, '' , None , '/foo', False, '/bar' , False)), (ChangeProfileRule('safe' , '/foo', '/bar') , exp(False, False, False, '' , 'safe' , '/foo', False, '/bar' , False)), (ChangeProfileRule('unsafe', '/foo', '/bar') , exp(False, False, False, '' , 'unsafe', '/foo', False, '/bar' , False)), (ChangeProfileRule(None , '/foo', ChangeProfileRule.ALL) , exp(False, False, False, '' , None , '/foo', False, None , True )), (ChangeProfileRule(None , ChangeProfileRule.ALL, '/bar') , exp(False, False, False, '' , None , None , True , '/bar' , False)), (ChangeProfileRule(None , ChangeProfileRule.ALL, ChangeProfileRule.ALL) , exp(False, False, False, '' , None, None , True , None , True )), ] def _run_test(self, obj, expected): self._compare_obj(obj, expected) class InvalidChangeProfileInit(AATest): tests = [ # init params expected exception ([None , '/foo', '' ] , AppArmorBug), # empty targetprofile ([None , '' , '/bar' ] , AppArmorBug), # empty execcond ([None , ' ', '/bar' ] , AppArmorBug), # whitespace execcond ([None , '/foo', ' ' ] , AppArmorBug), # whitespace targetprofile ([None , 'xyxy', '/bar' ] , AppArmorException), # invalid execcond ([None , dict(), '/bar' ] , AppArmorBug), # wrong type for execcond ([None , None , '/bar' ] , AppArmorBug), # wrong type for execcond ([None , '/foo', dict() ] , AppArmorBug), # wrong type for targetprofile ([None , '/foo', None ] , AppArmorBug), # wrong type for targetprofile (['maybe' , '/foo', '/bar' ] , AppArmorBug), # invalid keyword for execmode ] def _run_test(self, params, expected): with self.assertRaises(expected): ChangeProfileRule(params[0], params[1], params[2]) def test_missing_params_1(self): with self.assertRaises(TypeError): ChangeProfileRule() def test_missing_params_2(self): with self.assertRaises(TypeError): ChangeProfileRule('inet') class InvalidChangeProfileTest(AATest): def _check_invalid_rawrule(self, rawrule): obj = None self.assertFalse(ChangeProfileRule.match(rawrule)) with self.assertRaises(AppArmorException): obj = ChangeProfileRule(ChangeProfileRule.parse(rawrule)) self.assertIsNone(obj, 'ChangeProfileRule handed back an object unexpectedly') def test_invalid_net_missing_comma(self): self._check_invalid_rawrule('change_profile') # missing comma def test_invalid_net_non_ChangeProfileRule(self): self._check_invalid_rawrule('dbus,') # not a change_profile rule def test_empty_net_data_1(self): obj = ChangeProfileRule(None, '/foo', '/bar') obj.execcond = '' # no execcond set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) def test_empty_net_data_2(self): obj = ChangeProfileRule(None, '/foo', '/bar') obj.targetprofile = '' # no targetprofile set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) class WriteChangeProfileTestAATest(AATest): tests = [ # raw rule clean rule (' change_profile , # foo ' , 'change_profile, # foo'), (' audit change_profile /foo,' , 'audit change_profile /foo,'), (' deny change_profile /foo -> bar,# foo bar' , 'deny change_profile /foo -> bar, # foo bar'), (' deny change_profile /foo ,# foo bar' , 'deny change_profile /foo, # foo bar'), (' allow change_profile -> /bar ,# foo bar' , 'allow change_profile -> /bar, # foo bar'), (' allow change_profile unsafe /** -> /bar ,# foo bar' , 'allow change_profile unsafe /** -> /bar, # foo bar'), (' allow change_profile "/fo o" -> "/b ar",' , 'allow change_profile "/fo o" -> "/b ar",'), ] def _run_test(self, rawrule, expected): self.assertTrue(ChangeProfileRule.match(rawrule)) obj = ChangeProfileRule.parse(rawrule) clean = obj.get_clean() raw = obj.get_raw() self.assertEqual(expected.strip(), clean, 'unexpected clean rule') self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule') def test_write_manually(self): obj = ChangeProfileRule(None, '/foo', 'bar', allow_keyword=True) expected = ' allow change_profile /foo -> bar,' self.assertEqual(expected, obj.get_clean(2), 'unexpected clean rule') self.assertEqual(expected, obj.get_raw(2), 'unexpected raw rule') class ChangeProfileCoveredTest(AATest): def _run_test(self, param, expected): obj = ChangeProfileRule.parse(self.rule) check_obj = ChangeProfileRule.parse(param) self.assertTrue(ChangeProfileRule.match(param)) self.assertEqual(obj.is_equal(check_obj), expected[0], 'Mismatch in is_equal, expected %s' % expected[0]) self.assertEqual(obj.is_equal(check_obj, True), expected[1], 'Mismatch in is_equal/strict, expected %s' % expected[1]) self.assertEqual(obj.is_covered(check_obj), expected[2], 'Mismatch in is_covered, expected %s' % expected[2]) self.assertEqual(obj.is_covered(check_obj, True, True), expected[3], 'Mismatch in is_covered/exact, expected %s' % expected[3]) class ChangeProfileCoveredTest_01(ChangeProfileCoveredTest): rule = 'change_profile /foo,' tests = [ # rule equal strict equal covered covered exact (' change_profile,' , [ False , False , False , False ]), (' change_profile /foo,' , [ True , True , True , True ]), (' change_profile safe /foo,' , [ True , False , True , True ]), (' change_profile unsafe /foo,' , [ False , False , False , False ]), (' change_profile /foo, # comment', [ True , False , True , True ]), (' allow change_profile /foo,' , [ True , False , True , True ]), (' change_profile /foo,' , [ True , False , True , True ]), (' change_profile /foo -> /bar,' , [ False , False , True , True ]), (' change_profile /foo -> bar,' , [ False , False , True , True ]), ('audit change_profile /foo,' , [ False , False , False , False ]), ('audit change_profile,' , [ False , False , False , False ]), (' change_profile /asdf,' , [ False , False , False , False ]), (' change_profile -> /bar,' , [ False , False , False , False ]), ('audit deny change_profile /foo,' , [ False , False , False , False ]), (' deny change_profile /foo,' , [ False , False , False , False ]), ] class ChangeProfileCoveredTest_02(ChangeProfileCoveredTest): rule = 'audit change_profile /foo,' tests = [ # rule equal strict equal covered covered exact ( 'change_profile /foo,' , [ False , False , True , False ]), ('audit change_profile /foo,' , [ True , True , True , True ]), ( 'change_profile /foo -> /bar,' , [ False , False , True , False ]), ( 'change_profile safe /foo -> /bar,' , [ False , False , True , False ]), ('audit change_profile /foo -> /bar,' , [ False , False , True , True ]), # XXX is "covered exact" correct here? ( 'change_profile,' , [ False , False , False , False ]), ('audit change_profile,' , [ False , False , False , False ]), (' change_profile -> /bar,' , [ False , False , False , False ]), ] class ChangeProfileCoveredTest_03(ChangeProfileCoveredTest): rule = 'change_profile /foo -> /bar,' tests = [ # rule equal strict equal covered covered exact ( 'change_profile /foo -> /bar,' , [ True , True , True , True ]), ('allow change_profile /foo -> /bar,' , [ True , False , True , True ]), ( 'change_profile /foo,' , [ False , False , False , False ]), ( 'change_profile,' , [ False , False , False , False ]), ( 'change_profile /foo -> /xyz,' , [ False , False , False , False ]), ('audit change_profile,' , [ False , False , False , False ]), ('audit change_profile /foo -> /bar,' , [ False , False , False , False ]), ( 'change_profile -> /bar,' , [ False , False , False , False ]), ( 'change_profile,' , [ False , False , False , False ]), ] class ChangeProfileCoveredTest_04(ChangeProfileCoveredTest): rule = 'change_profile,' tests = [ # rule equal strict equal covered covered exact ( 'change_profile,' , [ True , True , True , True ]), ('allow change_profile,' , [ True , False , True , True ]), ( 'change_profile /foo,' , [ False , False , True , True ]), ( 'change_profile /xyz -> bar,' , [ False , False , True , True ]), ( 'change_profile -> /bar,' , [ False , False , True , True ]), ( 'change_profile /foo -> /bar,' , [ False , False , True , True ]), ('audit change_profile,' , [ False , False , False , False ]), ('deny change_profile,' , [ False , False , False , False ]), ] class ChangeProfileCoveredTest_05(ChangeProfileCoveredTest): rule = 'deny change_profile /foo,' tests = [ # rule equal strict equal covered covered exact ( 'deny change_profile /foo,' , [ True , True , True , True ]), ('audit deny change_profile /foo,' , [ False , False , False , False ]), ( 'change_profile /foo,' , [ False , False , False , False ]), # XXX should covered be true here? ( 'deny change_profile /bar,' , [ False , False , False , False ]), ( 'deny change_profile,' , [ False , False , False , False ]), ] class ChangeProfileCoveredTest_06(ChangeProfileCoveredTest): rule = 'change_profile safe /foo,' tests = [ # rule equal strict equal covered covered exact ( 'deny change_profile /foo,' , [ False , False , False , False ]), ('audit deny change_profile /foo,' , [ False , False , False , False ]), ( 'change_profile /foo,' , [ True , False , True , True ]), ( 'deny change_profile /bar,' , [ False , False , False , False ]), ( 'deny change_profile,' , [ False , False , False , False ]), ] class ChangeProfileCoveredTest_Invalid(AATest): def test_borked_obj_is_covered_1(self): obj = ChangeProfileRule.parse('change_profile /foo,') testobj = ChangeProfileRule(None, '/foo', '/bar') testobj.execcond = '' with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_borked_obj_is_covered_2(self): obj = ChangeProfileRule.parse('change_profile /foo,') testobj = ChangeProfileRule(None, '/foo', '/bar') testobj.targetprofile = '' with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_invalid_is_covered(self): obj = ChangeProfileRule.parse('change_profile /foo,') testobj = BaseRule() # different type with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_invalid_is_equal(self): obj = ChangeProfileRule.parse('change_profile -> /bar,') testobj = BaseRule() # different type with self.assertRaises(AppArmorBug): obj.is_equal(testobj) class ChangeProfileLogprofHeaderTest(AATest): tests = [ ('change_profile,', [ _('Exec Condition'), _('ALL'), _('Target Profile'), _('ALL'), ]), ('change_profile -> /bin/ping,', [ _('Exec Condition'), _('ALL'), _('Target Profile'), '/bin/ping',]), ('change_profile /bar -> /bin/bar,', [ _('Exec Condition'), '/bar', _('Target Profile'), '/bin/bar', ]), ('change_profile safe /foo,', [ _('Exec Mode'), 'safe', _('Exec Condition'), '/foo', _('Target Profile'), _('ALL'), ]), ('audit change_profile -> /bin/ping,', [_('Qualifier'), 'audit', _('Exec Condition'), _('ALL'), _('Target Profile'), '/bin/ping',]), ('deny change_profile /bar -> /bin/bar,', [_('Qualifier'), 'deny', _('Exec Condition'), '/bar', _('Target Profile'), '/bin/bar', ]), ('allow change_profile unsafe /foo,', [_('Qualifier'), 'allow', _('Exec Mode'), 'unsafe', _('Exec Condition'), '/foo', _('Target Profile'), _('ALL'), ]), ('audit deny change_profile,', [_('Qualifier'), 'audit deny', _('Exec Condition'), _('ALL'), _('Target Profile'), _('ALL'), ]), ] def _run_test(self, params, expected): obj = ChangeProfileRule._parse(params) self.assertEqual(obj.logprof_header(), expected) # --- tests for ChangeProfileRuleset --- # class ChangeProfileRulesTest(AATest): def test_empty_ruleset(self): ruleset = ChangeProfileRuleset() ruleset_2 = ChangeProfileRuleset() self.assertEqual([], ruleset.get_raw(2)) self.assertEqual([], ruleset.get_clean(2)) self.assertEqual([], ruleset_2.get_raw(2)) self.assertEqual([], ruleset_2.get_clean(2)) def test_ruleset_1(self): ruleset = ChangeProfileRuleset() rules = [ 'change_profile -> /bar,', 'change_profile /foo,', ] expected_raw = [ 'change_profile -> /bar,', 'change_profile /foo,', '', ] expected_clean = [ 'change_profile -> /bar,', 'change_profile /foo,', '', ] for rule in rules: ruleset.add(ChangeProfileRule.parse(rule)) self.assertEqual(expected_raw, ruleset.get_raw()) self.assertEqual(expected_clean, ruleset.get_clean()) def test_ruleset_2(self): ruleset = ChangeProfileRuleset() rules = [ 'change_profile /foo -> /bar,', 'allow change_profile /asdf,', 'deny change_profile -> xy, # example comment', ] expected_raw = [ ' change_profile /foo -> /bar,', ' allow change_profile /asdf,', ' deny change_profile -> xy, # example comment', '', ] expected_clean = [ ' deny change_profile -> xy, # example comment', '', ' allow change_profile /asdf,', ' change_profile /foo -> /bar,', '', ] for rule in rules: ruleset.add(ChangeProfileRule.parse(rule)) self.assertEqual(expected_raw, ruleset.get_raw(1)) self.assertEqual(expected_clean, ruleset.get_clean(1)) class ChangeProfileGlobTestAATest(AATest): def setUp(self): self.ruleset = ChangeProfileRuleset() def test_glob_1(self): self.assertEqual(self.ruleset.get_glob('change_profile /foo,'), 'change_profile,') # not supported or used yet, glob behaviour not decided yet # def test_glob_2(self): # self.assertEqual(self.ruleset.get_glob('change_profile /foo -> /bar,'), 'change_profile -> /bar,') def test_glob_ext(self): with self.assertRaises(NotImplementedError): # get_glob_ext is not available for change_profile rules self.ruleset.get_glob_ext('change_profile /foo -> /bar,') class ChangeProfileDeleteTestAATest(AATest): pass setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/severity.db0000644000175000017500000002451113502024172015510 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2002-2005 Novell/SUSE # Copyright (C) 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ # Allow this process to 0wn the machine: CAP_SYS_ADMIN 10 CAP_SYS_CHROOT 10 CAP_SYS_MODULE 10 CAP_SYS_PTRACE 10 CAP_SYS_RAWIO 10 CAP_MAC_ADMIN 10 CAP_MAC_OVERRIDE 10 # Allow other processes to 0wn the machine: CAP_SETPCAP 9 CAP_SETFCAP 9 CAP_CHOWN 9 CAP_FSETID 9 CAP_MKNOD 9 CAP_LINUX_IMMUTABLE 9 CAP_DAC_OVERRIDE 9 CAP_SETGID 9 CAP_SETUID 9 CAP_FOWNER 9 # Denial of service, bypass audit controls, information leak CAP_SYS_TIME 8 CAP_NET_ADMIN 8 CAP_SYS_RESOURCE 8 CAP_KILL 8 CAP_IPC_OWNER 8 CAP_SYS_PACCT 8 CAP_SYS_BOOT 8 CAP_NET_BIND_SERVICE 8 CAP_NET_RAW 8 CAP_SYS_NICE 8 CAP_LEASE 8 CAP_IPC_LOCK 8 CAP_SYS_TTY_CONFIG 8 CAP_AUDIT_CONTROL 8 CAP_AUDIT_WRITE 8 CAP_SYSLOG 8 CAP_WAKE_ALARM 8 CAP_BLOCK_SUSPEND 8 CAP_DAC_READ_SEARCH 7 # unused CAP_NET_BROADCAST 0 # filename r w x # 'hard drives' are generally 4 10 0 /**/lost+found/** 5 5 0 /boot/** 7 10 0 /etc/passwd* 4 8 0 /etc/group* 4 8 0 /etc/shadow* 7 9 0 /etc/shadow* 7 9 0 /home/*/.ssh/** 7 9 0 /home/*/.gnupg/** 5 7 0 /home/** 4 6 0 /srv/** 4 6 0 /proc/** 6 9 0 /proc/sys/kernel/hotplug 2 10 0 /proc/sys/kernel/modprobe 2 10 0 /proc/kallsyms 7 0 0 /sys/** 4 8 0 /sys/power/state 2 8 0 /sys/firmware/** 2 10 0 /dev/pts/* 8 9 0 /dev/ptmx 8 9 0 /dev/pty* 8 9 0 /dev/null 0 0 0 /dev/adbmouse 3 8 0 /dev/ataraid 9 10 0 /dev/zero 0 0 0 /dev/agpgart* 8 10 0 /dev/aio 3 3 0 /dev/cbd/* 5 5 0 /dev/cciss/* 4 10 0 /dev/capi* 4 6 0 /dev/cfs0 4 10 0 /dev/compaq/* 4 10 0 /dev/cdouble* 4 8 0 /dev/cpu** 5 5 0 /dev/cpu**microcode 1 10 0 /dev/double* 4 8 0 /dev/hd* 4 10 0 /dev/sd* 4 10 0 /dev/ida/* 4 10 0 /dev/input/* 4 8 0 /dev/mapper/control 4 10 0 /dev/*mem 8 10 0 /dev/loop* 4 10 0 /dev/lp* 0 4 0 /dev/md* 4 10 0 /dev/msr 4 10 0 /dev/nb* 4 10 0 /dev/ram* 8 10 0 /dev/rd/* 4 10 0 /dev/*random 3 1 0 /dev/sbpcd* 4 0 0 /dev/rtc 6 0 0 /dev/sd* 4 10 0 /dev/sc* 4 10 0 /dev/sg* 4 10 0 /dev/st* 4 10 0 /dev/snd/* 3 8 0 /dev/usb/mouse* 4 6 0 /dev/usb/hid* 4 6 0 /dev/usb/tty* 4 6 0 /dev/tty* 8 9 0 /dev/stderr 0 0 0 /dev/stdin 0 0 0 /dev/stdout 0 0 0 /dev/ubd* 4 10 0 /dev/usbmouse* 4 6 0 /dev/userdma 8 10 0 /dev/vcs* 8 9 0 /dev/xta* 4 10 0 /dev/zero 0 0 0 /dev/inittcl 8 10 0 /dev/log 5 7 0 /etc/fstab 3 8 0 /etc/mtab 3 5 0 /etc/SuSEconfig/* 1 8 0 /etc/X11/* 2 7 0 /etc/X11/xinit/* 2 8 0 /etc/SuSE-release 1 5 0 /etc/issue* 1 3 0 /etc/motd 1 3 0 /etc/aliases.d/* 1 7 0 /etc/cron* 1 9 0 /etc/cups/* 2 7 0 /etc/default/* 3 8 0 /etc/init.d/* 1 10 0 /etc/permissions.d/* 1 8 0 /etc/ppp/* 2 6 0 /etc/ppp/*secrets 8 6 0 /etc/profile.d/* 1 8 0 /etc/skel/* 0 7 0 /etc/sysconfig/* 4 10 0 /etc/xinetd.d/* 1 9 0 /etc/termcap/* 1 4 0 /etc/ld.so.* 1 9 0 /etc/pam.d/* 3 9 0 /etc/udev/* 3 9 0 /etc/insserv.conf 3 6 0 /etc/security/* 1 9 0 /etc/securetty 0 7 0 /etc/sudoers 4 9 0 /etc/hotplug/* 2 10 0 /etc/xinitd.conf 1 9 0 /etc/gpm/* 2 10 0 /etc/ssl/** 2 7 0 /etc/shadow* 5 9 0 /etc/bash.bashrc 1 9 0 /etc/csh.cshrc 1 9 0 /etc/csh.login 1 9 0 /etc/inittab 1 10 0 /etc/profile* 1 9 0 /etc/shells 1 5 0 /etc/alternatives 1 6 0 /etc/sysctl.conf 3 7 0 /etc/dev.d/* 1 8 0 /etc/manpath.config 1 6 0 /etc/permissions* 1 8 0 /etc/evms.conf 3 8 0 /etc/exports 3 8 0 /etc/samba/* 5 8 0 /etc/ssh/* 3 8 0 /etc/ssh/ssh_host_*key 8 8 0 /etc/krb5.conf 4 8 0 /etc/ntp.conf 3 8 0 /etc/auto.* 3 8 0 /etc/postfix/* 3 7 0 /etc/postfix/*passwd* 6 7 0 /etc/postfix/*cert* 6 7 0 /etc/foomatic/* 3 5 0 /etc/printcap 3 5 0 /etc/youservers 4 9 0 /etc/grub.conf 7 10 0 /etc/modules.conf 4 10 0 /etc/resolv.conf 2 7 0 /etc/apache2/** 3 7 0 /etc/apache2/**ssl** 7 7 0 /etc/subdomain.d/** 6 10 0 /etc/apparmor.d/** 6 10 0 /etc/apparmor/** 6 10 0 /var/log/** 3 8 0 /var/adm/SuSEconfig/** 3 8 0 /var/adm/** 3 7 0 /var/lib/rpm/** 4 8 0 /var/run/nscd/* 3 3 0 /var/run/.nscd_socket 3 3 0 /usr/share/doc/** 1 1 0 /usr/share/man/** 3 5 0 /usr/X11/man/** 3 5 0 /usr/share/info/** 2 4 0 /usr/share/java/** 2 5 0 /usr/share/locale/** 2 4 0 /usr/share/sgml/** 2 4 0 /usr/share/YaST2/** 3 9 0 /usr/share/ghostscript/** 3 5 0 /usr/share/terminfo/** 1 8 0 /usr/share/latex2html/** 2 4 0 /usr/share/cups/** 5 6 0 /usr/share/susehelp/** 2 6 0 /usr/share/susehelp/cgi-bin/** 3 7 7 /usr/share/zoneinfo/** 2 7 0 /usr/share/zsh/** 3 6 0 /usr/share/vim/** 3 8 0 /usr/share/groff/** 3 7 0 /usr/share/vnc/** 3 8 0 /usr/share/wallpapers/** 2 4 0 /usr/X11** 3 8 5 /usr/X11*/bin/XFree86 3 8 8 /usr/X11*/bin/Xorg 3 8 8 /usr/X11*/bin/sux 3 8 8 /usr/X11*/bin/xconsole 3 7 7 /usr/X11*/bin/xhost 3 7 7 /usr/X11*/bin/xauth 3 7 7 /usr/X11*/bin/ethereal 3 6 8 /usr/lib/ooo-** 3 6 5 /usr/lib/lsb/** 2 8 8 /usr/lib/pt_chwon 2 8 5 /usr/lib/tcl** 2 5 3 /usr/lib/lib*so* 3 8 4 /usr/lib/iptables/* 2 8 2 /usr/lib/perl5/** 4 10 6 /usr/lib/*/perl/** 4 10 6 /usr/lib/*/perl5/** 4 10 6 /usr/lib/gconv/* 4 7 4 /usr/lib/locale/** 4 8 0 /usr/lib/jvm/** 5 7 5 /usr/lib/sasl*/** 5 8 4 /usr/lib/jvm-exports/** 5 7 5 /usr/lib/jvm-private/** 5 7 5 /usr/lib/python*/** 5 7 5 /usr/lib/libkrb5* 4 8 4 /usr/lib/postfix/* 4 7 4 /usr/lib/rpm/** 4 8 6 /usr/lib/rpm/gnupg/** 4 9 0 /usr/lib/apache2** 4 7 4 /usr/lib/mailman/** 4 6 4 /usr/bin/ldd 1 7 4 /usr/bin/netcat 5 7 8 /usr/bin/clear 2 6 3 /usr/bin/reset 2 6 3 /usr/bin/tput 2 6 3 /usr/bin/tset 2 6 3 /usr/bin/file 2 6 3 /usr/bin/ftp 3 7 5 /usr/bin/busybox 4 8 6 /usr/bin/rbash 4 8 5 /usr/bin/screen 3 6 5 /usr/bin/getfacl 3 7 4 /usr/bin/setfacl 3 7 9 /usr/bin/*awk* 3 7 7 /usr/bin/sudo 2 9 10 /usr/bin/lsattr 2 6 5 /usr/bin/chattr 2 7 8 /usr/bin/sed 3 7 6 /usr/bin/grep 2 7 2 /usr/bin/chroot 2 6 10 /usr/bin/dircolors 2 9 3 /usr/bin/cut 2 7 2 /usr/bin/du 2 7 3 /usr/bin/env 2 7 2 /usr/bin/head 2 7 2 /usr/bin/tail 2 7 2 /usr/bin/install 2 8 4 /usr/bin/link 2 6 4 /usr/bin/logname 2 6 2 /usr/bin/md5sum 2 8 3 /usr/bin/mkfifo 2 6 10 /usr/bin/nice 2 7 7 /usr/bin/nohup 2 7 7 /usr/bin/printf 2 7 1 /usr/bin/readlink 2 7 3 /usr/bin/seq 2 7 1 /usr/bin/sha1sum 2 8 3 /usr/bin/shred 2 7 3 /usr/bin/sort 2 7 3 /usr/bin/split 2 7 3 /usr/bin/stat 2 7 4 /usr/bin/sum 2 8 3 /usr/bin/tac 2 7 3 /usr/bin/tail 3 8 4 /usr/bin/tee 2 7 3 /usr/bin/test 2 8 4 /usr/bin/touch 2 7 3 /usr/bin/tr 2 8 3 /usr/bin/tsort 2 7 3 /usr/bin/tty 2 7 3 /usr/bin/unexpand 2 7 3 /usr/bin/uniq 2 7 3 /usr/bin/unlink 2 8 4 /usr/bin/uptime 2 7 3 /usr/bin/users 2 8 4 /usr/bin/vdir 2 8 4 /usr/bin/wc 2 7 3 /usr/bin/who 2 8 4 /usr/bin/whoami 2 8 4 /usr/bin/yes 1 6 1 /usr/bin/ed 2 7 5 /usr/bin/red 2 7 4 /usr/bin/find 2 8 5 /usr/bin/xargs 2 7 5 /usr/bin/ispell 2 7 4 /usr/bin/a2p 2 7 5 /usr/bin/perlcc 2 7 5 /usr/bin/perldoc 2 7 5 /usr/bin/pod2* 2 7 5 /usr/bin/prove 2 7 5 /usr/bin/perl 2 10 7 /usr/bin/perl* 2 10 7 /usr/bin/suidperl 2 8 8 /usr/bin/csh 2 8 8 /usr/bin/tcsh 2 8 8 /usr/bin/tree 2 6 5 /usr/bin/last 2 7 5 /usr/bin/lastb 2 7 5 /usr/bin/utmpdump 2 6 5 /usr/bin/alsamixer 2 6 8 /usr/bin/amixer 2 6 8 /usr/bin/amidi 2 6 8 /usr/bin/aoss 2 6 8 /usr/bin/aplay 2 6 8 /usr/bin/aplaymidi 2 6 8 /usr/bin/arecord 2 6 8 /usr/bin/arecordmidi 2 6 8 /usr/bin/aseqnet 2 6 8 /usr/bin/aserver 2 6 8 /usr/bin/iecset 2 6 8 /usr/bin/rview 2 6 5 /usr/bin/ex 2 7 5 /usr/bin/enscript 2 6 5 /usr/bin/genscript 2 6 5 /usr/bin/xdelta 2 6 5 /usr/bin/edit 2 6 5 /usr/bin/vimtutor 2 6 5 /usr/bin/rvim 2 6 5 /usr/bin/vim 2 8 7 /usr/bin/vimdiff 2 8 7 /usr/bin/aspell 2 6 5 /usr/bin/xxd 2 6 5 /usr/bin/spell 2 6 5 /usr/bin/eqn 2 6 5 /usr/bin/eqn2graph 2 6 5 /usr/bin/word-list-compress 2 6 4 /usr/bin/afmtodit 2 6 4 /usr/bin/hpf2dit 2 6 4 /usr/bin/geqn 2 6 4 /usr/bin/grn 2 6 4 /usr/bin/grodvi 2 6 4 /usr/bin/groff 2 6 5 /usr/bin/groffer 2 6 4 /usr/bin/grolj4 2 6 4 /usr/bin/grotty 2 6 4 /usr/bin/gtbl 2 6 4 /usr/bin/pic2graph 2 6 4 /usr/bin/indxbib 2 6 4 /usr/bin/lkbib 2 6 4 /usr/bin/lookbib 2 6 4 /usr/bin/mmroff 2 6 4 /usr/bin/neqn 2 6 4 /usr/bin/pfbtops 2 6 4 /usr/bin/pic 2 6 4 /usr/bin/tfmtodit 2 6 4 /usr/bin/tbl 2 6 4 /usr/bin/post-grohtml 2 6 4 /usr/bin/pre-grohtml 2 6 4 /usr/bin/refer 2 6 4 /usr/bin/soelim 2 6 4 /usr/bin/disable-paste 2 6 6 /usr/bin/troff 2 6 4 /usr/bin/strace-graph 2 6 4 /usr/bin/gpm-root 2 6 7 /usr/bin/hltest 2 6 7 /usr/bin/mev 2 6 6 /usr/bin/mouse-test 2 6 6 /usr/bin/strace 2 8 9 /usr/bin/scsiformat 2 7 10 /usr/bin/lsscsi 2 7 7 /usr/bin/scsiinfo 2 7 7 /usr/bin/sg_* 2 7 7 /usr/bin/build-classpath 2 6 6 /usr/bin/build-classpath-directory 2 6 6 /usr/bin/build-jar-repository 2 6 6 /usr/bin/diff-jars 2 6 6 /usr/bin/jvmjar 2 6 6 /usr/bin/rebuild-jar-repository 2 6 6 /usr/bin/scriptreplay 2 6 5 /usr/bin/cal 2 6 3 /usr/bin/chkdupexe 2 6 5 /usr/bin/col 2 6 4 /usr/bin/colcrt 2 6 4 /usr/bin/colrm 2 6 3 /usr/bin/column 2 6 4 /usr/bin/cytune 2 6 6 /usr/bin/ddate 2 6 3 /usr/bin/fdformat 2 6 6 /usr/bin/getopt 2 8 6 /usr/bin/hexdump 2 6 4 /usr/bin/hostid 2 6 4 /usr/bin/ipcrm 2 7 7 /usr/bin/ipcs 2 7 6 /usr/bin/isosize 2 6 4 /usr/bin/line 2 6 4 /usr/bin/look 2 6 5 /usr/bin/mcookie 2 7 5 /usr/bin/mesg 2 6 4 /usr/bin/namei 2 6 5 /usr/bin/rename 2 6 5 /usr/bin/renice 2 6 7 /usr/bin/rev 2 6 5 /usr/bin/script 2 6 6 /usr/bin/ChangeSymlinks 2 8 8 /usr/bin/setfdprm 2 6 7 /usr/bin/setsid 2 6 3 /usr/bin/setterm 2 6 5 /usr/bin/tailf 2 6 4 /usr/bin/time 2 6 4 /usr/bin/ul 2 6 4 /usr/bin/wall 2 6 5 /usr/bin/whereis 2 6 4 /usr/bin/which 2 6 3 /usr/bin/c_rehash 2 7 6 /usr/bin/openssl 2 8 6 /usr/bin/lsdev 2 6 5 /usr/bin/procinfo 2 6 5 /usr/bin/socklist 2 6 5 /usr/bin/filesize 2 6 3 /usr/bin/linkto 2 6 3 /usr/bin/mkinfodir 2 6 5 /usr/bin/old 2 6 4 /usr/bin/rpmlocate 2 6 5 /usr/bin/safe-rm 2 8 6 /usr/bin/safe-rmdir 2 8 6 /usr/bin/setJava 2 6 1 /usr/bin/vmstat 2 6 4 /usr/bin/top 2 6 6 /usr/bin/pinentry* 2 7 6 /usr/bin/free 2 8 4 /usr/bin/pmap 2 6 5 /usr/bin/slabtop 2 6 4 /usr/bin/tload 2 6 4 /usr/bin/watch 2 6 3 /usr/bin/w 2 6 4 /usr/bin/pstree.x11 2 6 4 /usr/bin/pstree 2 6 4 /usr/bin/snice 2 6 6 /usr/bin/skill 2 6 7 /usr/bin/pgrep 2 6 4 /usr/bin/killall 2 6 7 /usr/bin/curl 2 7 7 /usr/bin/slptool 2 7 8 /usr/bin/ldap* 2 7 7 /usr/bin/whatis 2 7 5 apparmor-2.13.3/utils/test/test-logparser.py0000644000175000017500000001237013502024172016654 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import unittest from apparmor.logparser import ReadLog class TestParseEvent(unittest.TestCase): def setUp(self): self.parser = ReadLog('', '', '', '') def test_parse_event_audit_1(self): event = 'type=AVC msg=audit(1345027352.096:499): apparmor="ALLOWED" operation="rename_dest" parent=6974 profile="/usr/sbin/httpd2-prefork//vhost_foo" name=2F686F6D652F7777772F666F6F2E6261722E696E2F68747470646F63732F61707061726D6F722F696D616765732F746573742F696D61676520312E6A7067 pid=20143 comm="httpd2-prefork" requested_mask="wc" denied_mask="wc" fsuid=30 ouid=30' parsed_event = self.parser.parse_event(event) self.assertEqual(parsed_event['name'], '/home/www/foo.bar.in/httpdocs/apparmor/images/test/image 1.jpg') self.assertEqual(parsed_event['profile'], '/usr/sbin/httpd2-prefork//vhost_foo') self.assertEqual(parsed_event['aamode'], 'PERMITTING') self.assertEqual(parsed_event['request_mask'], 'wc') self.assertIsNotNone(ReadLog.RE_LOG_ALL.search(event)) def test_parse_event_audit_2(self): event = 'type=AVC msg=audit(1322614918.292:4376): apparmor="ALLOWED" operation="file_perm" parent=16001 profile=666F6F20626172 name="/home/foo/.bash_history" pid=17011 comm="bash" requested_mask="rw" denied_mask="rw" fsuid=0 ouid=1000' parsed_event = self.parser.parse_event(event) self.assertEqual(parsed_event['name'], '/home/foo/.bash_history') self.assertEqual(parsed_event['profile'], 'foo bar') self.assertEqual(parsed_event['aamode'], 'PERMITTING') self.assertEqual(parsed_event['request_mask'], 'rw') self.assertIsNotNone(ReadLog.RE_LOG_ALL.search(event)) def test_parse_event_syslog_1(self): # from https://bugs.launchpad.net/apparmor/+bug/1399027 event = '2014-06-09T20:37:28.975070+02:00 geeko kernel: [21028.143765] type=1400 audit(1402339048.973:1421): apparmor="ALLOWED" operation="open" profile="/home/cb/linuxtag/apparmor/scripts/hello" name="/dev/tty" pid=14335 comm="hello" requested_mask="rw" denied_mask="rw" fsuid=1000 ouid=0' parsed_event = self.parser.parse_event(event) self.assertEqual(parsed_event['name'], '/dev/tty') self.assertEqual(parsed_event['profile'], '/home/cb/linuxtag/apparmor/scripts/hello') self.assertEqual(parsed_event['aamode'], 'PERMITTING') self.assertEqual(parsed_event['request_mask'], 'rw') self.assertIsNotNone(ReadLog.RE_LOG_ALL.search(event)) def test_parse_event_syslog_2(self): # from https://bugs.launchpad.net/apparmor/+bug/1399027 event = 'Dec 7 13:18:59 rosa kernel: audit: type=1400 audit(1417954745.397:82): apparmor="ALLOWED" operation="open" profile="/home/simi/bin/aa-test" name="/usr/bin/" pid=3231 comm="ls" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0' parsed_event = self.parser.parse_event(event) self.assertEqual(parsed_event['name'], '/usr/bin/') self.assertEqual(parsed_event['profile'], '/home/simi/bin/aa-test') self.assertEqual(parsed_event['aamode'], 'PERMITTING') self.assertEqual(parsed_event['request_mask'], 'r') self.assertIsNotNone(ReadLog.RE_LOG_ALL.search(event)) def test_parse_disconnected_path(self): # from https://bugzilla.opensuse.org/show_bug.cgi?id=918787 event = 'type=AVC msg=audit(1424425690.883:716630): apparmor="ALLOWED" operation="file_mmap" info="Failed name lookup - disconnected path" error=-13 profile="/sbin/klogd" name="var/run/nscd/passwd" pid=25333 comm="id" requested_mask="r" denied_mask="r" fsuid=1002 ouid=0' parsed_event = self.parser.parse_event(event) self.assertEqual(parsed_event, { 'aamode': 'ERROR', # aamode for disconnected paths overridden aamode in parse_event() 'active_hat': None, 'attr': None, 'denied_mask': 'r', 'error_code': 13, 'fsuid': 1002, 'info': 'Failed name lookup - disconnected path', 'magic_token': 0, 'name': 'var/run/nscd/passwd', 'name2': None, 'operation': 'file_mmap', 'ouid': 0, 'parent': 0, 'pid': 25333, 'profile': '/sbin/klogd', 'request_mask': 'r', 'resource': 'Failed name lookup - disconnected path', 'task': 0, 'time': 1424425690, 'family': None, 'protocol': None, 'sock_type': None, }) self.assertIsNotNone(ReadLog.RE_LOG_ALL.search(event)) if __name__ == "__main__": unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-libapparmor-test_multi.py0000644000175000017500000002640413502024172021360 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2015-2018 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import unittest from common_test import AATest, setup_all_loops, setup_aa, read_file import os from apparmor.common import open_file_read import apparmor.aa from apparmor.logparser import ReadLog from apparmor.profile_list import ProfileList class TestLibapparmorTestMulti(AATest): '''Parse all libraries/libapparmor/testsuite/test_multi tests and compare the result with the *.out files''' tests = 'invalid' # filled by parse_test_profiles() def _run_test(self, params, expected): # tests[][expected] is a dummy, replace it with the real values expected = self._parse_libapparmor_test_multi(params) with open_file_read('%s.in' % params) as f_in: loglines = f_in.readlines() loglines2 = [] for line in loglines: if line.strip(): loglines2 += [line] self.assertEqual(len(loglines2), 1, '%s.in should only contain one line!' % params) parser = ReadLog('', '', '', '') parsed_event = parser.parse_event(loglines2[0]) if parsed_event and expected: parsed_items = dict(parsed_event.items()) # check if the line passes the regex in logparser.py if not parser.RE_LOG_ALL.search(loglines2[0]): raise Exception("Log event doesn't match RE_LOG_ALL") for label in expected: if label in [ 'file', # filename of the *.in file 'event_type', # mapped to aamode 'audit_id', 'audit_sub_id', # not set nor relevant 'comm', # not set, and not too useful # XXX most of the keywords listed below mean "TODO" 'fsuid', 'ouid', # file events 'flags', 'fs_type', # mount 'namespace', # file_lock only?? (at least the tests don't contain this in other event types with namespace) 'net_local_addr', 'net_foreign_addr', 'net_local_port', 'net_foreign_port', # detailed network events 'peer', 'signal', # signal 'src_name', # pivotroot 'dbus_bus', 'dbus_interface', 'dbus_member', 'dbus_path', # dbus 'peer_pid', 'peer_profile', # dbus ]: pass elif parsed_items['operation'] == 'exec' and label in ['sock_type', 'family', 'protocol']: pass # XXX 'exec' + network? really? elif parsed_items['operation'] == 'ptrace' and label == 'name2' and params.endswith('/ptrace_garbage_lp1689667_1'): pass # libapparmor would better qualify this case as invalid event elif not parsed_items.get(label, None): raise Exception('parsed_items[%s] not set' % label) elif not expected.get(label, None): raise Exception('expected[%s] not set' % label) else: self.assertEqual(str(parsed_items[label]), expected[label], '%s differs' % label) elif expected: self.assertIsNone(parsed_event) # that's why we end up here self.assertEqual(dict(), expected, 'parsed_event is none') # effectively print the content of expected elif parsed_event: self.assertIsNone(expected) # that's why we end up here self.assertEqual(parsed_event, dict(), 'expected is none') # effectively print the content of parsed_event else: self.assertIsNone(expected) # that's why we end up here self.assertIsNone(parsed_event) # that's why we end up here self.assertEqual(parsed_event, expected) # both are None # list of labels that use a different name in logparser.py than in the test_multi *.out files # (additionally, .lower() is applied to all labels) label_map = { 'Mask': 'request_mask', 'Command': 'comm', 'Token': 'magic_token', 'ErrorCode': 'error_code', 'Network family': 'family', 'Socket type': 'sock_type', 'Local addr': 'net_local_addr', 'Foreign addr': 'net_foreign_addr', 'Local port': 'net_local_port', 'Foreign port': 'net_foreign_port', 'Audit subid': 'audit_sub_id', 'Attribute': 'attr', 'Epoch': 'time', } def _parse_libapparmor_test_multi(self, file_with_path): '''parse the libapparmor test_multi *.in tests and their expected result in *.out''' with open_file_read('%s.out' % file_with_path) as f_in: expected = f_in.readlines() if expected[0].rstrip('\n') != 'START': raise Exception("%s.out doesn't have 'START' in its first line! (%s)" % ( file_with_path, expected[0])) expected.pop(0) exresult = dict() for line in expected: label, value = line.split(':', 1) # test_multi doesn't always use the original labels :-/ if label in self.label_map.keys(): label = self.label_map[label] label = label.replace(' ', '_').lower() exresult[label] = value.strip() if not exresult['event_type'].startswith('AA_RECORD_'): raise Exception("event_type doesn't start with AA_RECORD_: %s in file %s" % (exresult['event_type'], file_with_path)) exresult['aamode'] = exresult['event_type'].replace('AA_RECORD_', '') if exresult['aamode'] == 'ALLOWED': exresult['aamode'] = 'PERMITTING' if exresult['aamode'] == 'DENIED': exresult['aamode'] = 'REJECTING' if exresult['event_type'] == 'AA_RECORD_INVALID': # or exresult.get('error_code', 0) != 0: # XXX should events with errors be ignored? exresult = None return exresult # tests that do not produce the expected profile (checked with assertNotEqual) log_to_profile_known_failures = [ 'testcase_dmesg_changeprofile_01', # change_profile not yet supported in logparser 'testcase_changeprofile_01', # change_profile not yet supported in logparser 'testcase_mount_01', # mount rules not yet supported in logparser 'testcase_pivotroot_01', # pivot_rot not yet supported in logparser # exec events 'testcase01', 'testcase12', 'testcase13', # null-* hats get ignored by handle_children() if it didn't see an exec event for that null-* hat 'syslog_datetime_01', 'syslog_datetime_02', 'syslog_datetime_03', 'syslog_datetime_04', 'syslog_datetime_05', 'syslog_datetime_06', 'syslog_datetime_07', 'syslog_datetime_08', 'syslog_datetime_09', 'syslog_datetime_10', 'syslog_datetime_11', 'syslog_datetime_12', 'syslog_datetime_13', 'syslog_datetime_14', 'syslog_datetime_15', 'syslog_datetime_16', 'syslog_datetime_17', 'syslog_datetime_18', 'testcase_network_send_receive', ] # tests that cause crashes or need user interaction (will be skipped) log_to_profile_skip = [ 'testcase31', # XXX AppArmorBug: Log contains unknown mode mrwIxl 'testcase_dmesg_changehat_negative_error', # fails in write_header -> quote_if_needed because data is None 'testcase_syslog_changehat_negative_error', # fails in write_header -> quote_if_needed because data is None 'testcase_changehat_01', # interactive, asks to add a hat ] class TestLogToProfile(AATest): '''Check if the libraries/libapparmor/testsuite/test_multi tests result in the expected profile''' tests = 'invalid' # filled by parse_test_profiles() def _run_test(self, params, expected): logfile = '%s.in' % params profile_dummy_file = 'AATest_does_exist' # we need to find out the profile name and aamode (complain vs. enforce mode) so that the test can access the correct place in storage parser = ReadLog('', '', '', '') parsed_event = parser.parse_event(read_file(logfile)) if not parsed_event: # AA_RECORD_INVALID return if params.split('/')[-1] in log_to_profile_skip: return aamode = parsed_event['aamode'] if aamode in['AUDIT', 'STATUS', 'HINT']: # ignore some event types # XXX maybe we shouldn't ignore AUDIT events? return if aamode not in ['PERMITTING', 'REJECTING']: raise Exception('Unexpected aamode %s' % parsed_event['aamode']) # cleanup apparmor.aa storage apparmor.aa.log = dict() apparmor.aa.aa = apparmor.aa.hasher() apparmor.aa.prelog = apparmor.aa.hasher() profile = parsed_event['profile'] hat = profile if '//' in profile: profile, hat = profile.split('//') apparmor.aa.active_profiles = ProfileList() # optional for now, might be needed one day # if profile.startswith('/'): # apparmor.aa.active_profiles.add(profile_dummy_file, profile, profile) # else: apparmor.aa.active_profiles.add(profile_dummy_file, profile, '') log_reader = ReadLog(dict(), logfile, apparmor.aa.active_profiles, '') log = log_reader.read_log('') for root in log: apparmor.aa.handle_children('', '', root) # interactive for exec events! log_dict = apparmor.aa.collapse_log() apparmor.aa.filelist = apparmor.aa.hasher() apparmor.aa.filelist[profile_dummy_file]['profiles'][profile] = True new_profile = apparmor.aa.serialize_profile(log_dict[aamode][profile], profile, None) expected_profile = read_file('%s.profile' % params) if params.split('/')[-1] in log_to_profile_known_failures: self.assertNotEqual(new_profile, expected_profile) # known failure else: self.assertEqual(new_profile, expected_profile) def find_test_multi(log_dir): '''find all log sniplets in the given log_dir''' log_dir = os.path.abspath(log_dir) tests = [] for root, dirs, files in os.walk(log_dir): for file in files: if file.endswith('.in'): file_with_path = os.path.join(root, file[:-3]) # filename without '.in' tests.append([file_with_path, True]) # True is a dummy testresult, parsing of the *.out files is done while running the tests elif file.endswith('.out') or file.endswith('.err') or file.endswith('.profile'): pass else: raise Exception('Found unknown file %s in libapparmor test_multi' % file) return tests print('Testing libapparmor test_multi tests...') TestLibapparmorTestMulti.tests = find_test_multi('../../libraries/libapparmor/testsuite/test_multi/') TestLogToProfile.tests = find_test_multi('../../libraries/libapparmor/testsuite/test_multi/') setup_aa(apparmor.aa) setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-profile-storage.py0000644000175000017500000000705513502024172017764 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2017 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import unittest from common_test import AATest, setup_all_loops from apparmor.common import AppArmorBug from apparmor.profile_storage import ProfileStorage, add_or_remove_flag, split_flags class TestUnknownKey(AATest): def AASetup(self): self.storage = ProfileStorage('/test/foo', 'hat', 'TEST') def test_read(self): with self.assertRaises(AppArmorBug): self.storage['foo'] def test_get(self): with self.assertRaises(AppArmorBug): self.storage.get('foo') def test_get_with_fallback(self): with self.assertRaises(AppArmorBug): self.storage.get('foo', 'bar') def test_set(self): with self.assertRaises(AppArmorBug): self.storage['foo'] = 'bar' class AaTest_add_or_remove_flag(AATest): tests = [ # existing flag(s) flag to change add or remove? expected flags ([ [], 'complain', True ], ['complain'] ), ([ [], 'complain', False ], [] ), ([ ['complain'], 'complain', True ], ['complain'] ), ([ ['complain'], 'complain', False ], [] ), ([ [], 'audit', True ], ['audit'] ), ([ [], 'audit', False ], [] ), ([ ['complain'], 'audit', True ], ['audit', 'complain'] ), ([ ['complain'], 'audit', False ], ['complain'] ), ([ '', 'audit', True ], ['audit'] ), ([ None, 'audit', False ], [] ), ([ 'complain', 'audit', True ], ['audit', 'complain'] ), ([ ' complain ', 'audit', False ], ['complain'] ), ] def _run_test(self, params, expected): new_flags = add_or_remove_flag(params[0], params[1], params[2]) self.assertEqual(new_flags, expected) class AaTest_split_flags(AATest): tests = [ (None , [] ), ('' , [] ), (' ' , [] ), (' , ' , [] ), ('complain' , ['complain'] ), (' complain attach_disconnected' , ['attach_disconnected', 'complain'] ), (' complain , attach_disconnected' , ['attach_disconnected', 'complain'] ), (' complain , , audit , , ' , ['audit', 'complain'] ), ] def _run_test(self, params, expected): split = split_flags(params) self.assertEqual(split, expected) setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-aamode.py0000644000175000017500000001134113502024172016101 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2014-2016 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import unittest from common_test import AATest, setup_all_loops import apparmor.aamode from apparmor.aamode import split_log_mode, str_to_mode, sub_str_to_mode, validate_log_mode from apparmor.common import AppArmorBug class AamodeTest_split_log_mode(AATest): def test_split_log_mode_1(self): self.assertEqual(split_log_mode(''), ('', '')) def test_split_log_mode_2(self): self.assertEqual(split_log_mode('r'), ('r', 'r')) def test_split_log_mode_3(self): self.assertEqual(split_log_mode('r::'), ('r', '')) def test_split_log_mode_4(self): self.assertEqual(split_log_mode('::r'), ('', 'r')) def test_split_log_mode_5(self): self.assertEqual(split_log_mode('r::w'), ('r', 'w')) def test_split_log_mode_6(self): self.assertEqual(split_log_mode('rw::rw'), ('rw', 'rw')) def test_split_log_mode_invalid_1(self): with self.assertRaises(AppArmorBug): split_log_mode('r::w::r') class AamodeTest_str_to_mode(AATest): tests = [ ('x', apparmor.aamode.AA_MAY_EXEC), ('w', apparmor.aamode.AA_MAY_WRITE), ('r', apparmor.aamode.AA_MAY_READ), ('a', apparmor.aamode.AA_MAY_APPEND), ('l', apparmor.aamode.AA_MAY_LINK), ('k', apparmor.aamode.AA_MAY_LOCK), ('m', apparmor.aamode.AA_EXEC_MMAP), ('i', apparmor.aamode.AA_EXEC_INHERIT), ('u', apparmor.aamode.AA_EXEC_UNCONFINED | apparmor.aamode.AA_EXEC_UNSAFE), ('U', apparmor.aamode.AA_EXEC_UNCONFINED), ('p', apparmor.aamode.AA_EXEC_PROFILE | apparmor.aamode.AA_EXEC_UNSAFE), ('P', apparmor.aamode.AA_EXEC_PROFILE), ('c', apparmor.aamode.AA_EXEC_CHILD | apparmor.aamode.AA_EXEC_UNSAFE), ('C', apparmor.aamode.AA_EXEC_CHILD), (None, set()), ] def _run_test(self, params, expected): mode = expected | apparmor.aamode.AA_OTHER(expected) #print("mode: %s params: %s str_to_mode(params): %s" % (mode, params, apparmor.aamode.str_to_mode(params))) self.assertEqual(mode, str_to_mode(params), 'mode is %s and expected string is %s'%(mode, expected)) class AamodeTest_sub_str_to_mode(AATest): def test_sub_str_to_mode_1(self): self.assertEqual(sub_str_to_mode(''), set()) def test_sub_str_to_mode_2(self): self.assertEqual(sub_str_to_mode('ix'), {'i', 'x'}) def test_sub_str_to_mode_3(self): self.assertEqual(sub_str_to_mode('rw'), {'r', 'w'}) def test_sub_str_to_mode_4(self): self.assertEqual(sub_str_to_mode('rPix'), {'i', 'P', 'r', 'x'}) def test_sub_str_to_mode_5(self): self.assertEqual(sub_str_to_mode('rPUx'), {'P', 'r', 'U', 'x'}) def test_sub_str_to_mode_6(self): self.assertEqual(sub_str_to_mode('cix'), {'i', 'x', 'C', 'execunsafe'}) def test_sub_str_to_mode_7(self): self.assertEqual(sub_str_to_mode('rwlk'), {'k', 'r', 'l', 'w'}) def test_sub_str_to_mode_dupes(self): self.assertEqual(sub_str_to_mode('rwrwrw'), {'r', 'w'}) def test_sub_str_to_mode_invalid_1(self): with self.assertRaises(AppArmorBug): sub_str_to_mode('asdf42') def test_sub_str_to_mode_invalid_2(self): import apparmor.aamode apparmor.aamode.MODE_HASH = {'x': 'foo'} # simulate MODE_HASH and MODE_MAP_SET getting out of sync with self.assertRaises(AppArmorBug): sub_str_to_mode('r') class AamodeTest_validate_log_mode(AATest): def test_validate_log_mode_1(self): self.assertTrue(validate_log_mode('a')) def test_validate_log_mode_2(self): self.assertTrue(validate_log_mode('rw')) def test_validate_log_mode_3(self): self.assertTrue(validate_log_mode('Pixrw')) def test_validate_log_mode_4(self): self.assertTrue(validate_log_mode('rrrr')) def test_validate_log_mode_invalid_1(self): self.assertFalse(validate_log_mode('c')) # 'c' (create) must be converted to 'a' before calling validate_log_mode() def test_validate_log_mode_invalid_2(self): self.assertFalse(validate_log_mode('R')) # only lowercase 'r' is valid def test_validate_log_mode_invalid_3(self): self.assertFalse(validate_log_mode('foo')) def test_validate_log_mode_invalid_4(self): self.assertFalse(validate_log_mode('')) setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-signal.py0000644000175000017500000010626013502024172016135 0ustar jjjj#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import unittest from collections import namedtuple from common_test import AATest, setup_all_loops from apparmor.rule.signal import SignalRule, SignalRuleset from apparmor.rule import BaseRule from apparmor.common import AppArmorException, AppArmorBug from apparmor.logparser import ReadLog from apparmor.translations import init_translation _ = init_translation() exp = namedtuple('exp', ['audit', 'allow_keyword', 'deny', 'comment', 'access', 'all_access', 'signal', 'all_signals', 'peer', 'all_peers']) # --- tests for single SignalRule --- # class SignalTest(AATest): def _compare_obj(self, obj, expected): self.assertEqual(expected.allow_keyword, obj.allow_keyword) self.assertEqual(expected.audit, obj.audit) self.assertEqual(expected.access, obj.access) self.assertEqual(expected.signal, obj.signal) if obj.peer: self.assertEqual(expected.peer, obj.peer.regex) else: self.assertEqual(expected.peer, obj.peer) self.assertEqual(expected.all_access, obj.all_access) self.assertEqual(expected.all_signals, obj.all_signals) self.assertEqual(expected.all_peers, obj.all_peers) self.assertEqual(expected.deny, obj.deny) self.assertEqual(expected.comment, obj.comment) class SignalTestParse(SignalTest): tests = [ # SignalRule object audit allow deny comment access all? signal all? peer all? ('signal,' , exp(False, False, False, '', None , True , None, True, None, True )), ('signal send,' , exp(False, False, False, '', {'send'}, False, None, True, None, True )), ('signal (send, receive),' , exp(False, False, False, '', {'send', 'receive'}, False, None, True, None, True )), ('signal send set=quit,' , exp(False, False, False, '', {'send'}, False, {'quit'}, False, None, True )), ('deny signal send set=quit, # cmt' , exp(False, False, True , ' # cmt', {'send'}, False, {'quit'}, False, None, True )), ('audit allow signal set=int,' , exp(True , True , False, '', None , True , {'int'}, False, None, True )), ('signal set=quit peer=unconfined,' , exp(False, False, False, '', None , True , {'quit'}, False, 'unconfined', False )), ('signal send set=(quit),' , exp(False, False, False, '', {'send'}, False, {'quit'}, False, None, True )), ('signal send set=(quit, int),' , exp(False, False, False, '', {'send'}, False, {'quit', 'int'}, False, None, True )), ('signal set=(quit, int),' , exp(False, False, False, '', None, True, {'quit', 'int'}, False, None, True )), ('signal send set = ( quit , int ) ,' , exp(False, False, False, '', {'send'}, False, {'quit', 'int'}, False, None, True )), ('signal peer=/foo,' , exp(False, False, False, '', None , True , None, True, '/foo', False )), ('signal r set=quit set=int peer=/foo,' , exp(False, False, False, '', {'r'}, False, {'quit', 'int'}, False, '/foo', False )), ] def _run_test(self, rawrule, expected): self.assertTrue(SignalRule.match(rawrule)) obj = SignalRule.parse(rawrule) self.assertEqual(rawrule.strip(), obj.raw_rule) self._compare_obj(obj, expected) class SignalTestParseInvalid(SignalTest): tests = [ ('signal foo,' , AppArmorException), ('signal foo bar,' , AppArmorException), ('signal foo int,' , AppArmorException), ('signal send bar,' , AppArmorException), ('signal send receive,' , AppArmorException), ('signal set=,' , AppArmorException), ('signal set=int set=,' , AppArmorException), ('signal set=invalid,' , AppArmorException), ('signal peer=,' , AppArmorException), ] def _run_test(self, rawrule, expected): self.assertTrue(SignalRule.match(rawrule)) # the above invalid rules still match the main regex! with self.assertRaises(expected): SignalRule.parse(rawrule) class SignalTestParseFromLog(SignalTest): def test_signal_from_log(self): parser = ReadLog('', '', '', '') event = 'type=AVC msg=audit(1409438250.564:201): apparmor="DENIED" operation="signal" profile="/usr/bin/pulseaudio" pid=2531 comm="pulseaudio" requested_mask="send" denied_mask="send" signal=term peer="/usr/bin/pulseaudio///usr/lib/pulseaudio/pulse/gconf-helper"' parsed_event = parser.parse_event(event) self.assertEqual(parsed_event, { 'request_mask': 'send', 'denied_mask': 'send', 'error_code': 0, 'magic_token': 0, 'parent': 0, 'profile': '/usr/bin/pulseaudio', 'signal': 'term', 'peer': '/usr/bin/pulseaudio///usr/lib/pulseaudio/pulse/gconf-helper', 'operation': 'signal', 'resource': None, 'info': None, 'aamode': 'REJECTING', 'time': 1409438250, 'active_hat': None, 'pid': 2531, 'task': 0, 'attr': None, 'name2': None, 'name': None, 'family': None, 'protocol': None, 'sock_type': None, }) obj = SignalRule(parsed_event['denied_mask'], parsed_event['signal'], parsed_event['peer'], log_event=parsed_event) # audit allow deny comment access all? signal all? peer all? expected = exp(False, False, False, '', {'send'}, False, {'term'}, False, '/usr/bin/pulseaudio///usr/lib/pulseaudio/pulse/gconf-helper', False) self._compare_obj(obj, expected) self.assertEqual(obj.get_raw(1), ' signal send set=term peer=/usr/bin/pulseaudio///usr/lib/pulseaudio/pulse/gconf-helper,') class SignalFromInit(SignalTest): tests = [ # SignalRule object audit allow deny comment access all? signal all? peer all? (SignalRule('r', 'hup', 'unconfined', deny=True) , exp(False, False, True , '' , {'r'}, False, {'hup'}, False, 'unconfined', False)), (SignalRule(('r', 'send'), ('hup', 'int'), '/bin/foo') , exp(False, False, False, '' , {'r', 'send'},False, {'hup', 'int'}, False, '/bin/foo', False)), (SignalRule(SignalRule.ALL, 'int', '/bin/foo') , exp(False, False, False, '' , None, True, {'int'}, False, '/bin/foo', False )), (SignalRule('rw', SignalRule.ALL, '/bin/foo') , exp(False, False, False, '' , {'rw'}, False, None, True, '/bin/foo', False )), (SignalRule('rw', ('int'), SignalRule.ALL) , exp(False, False, False, '' , {'rw'}, False, {'int'}, False, None, True )), (SignalRule(SignalRule.ALL, SignalRule.ALL, SignalRule.ALL) , exp(False, False, False, '' , None , True, None, True, None, True )), ] def _run_test(self, obj, expected): self._compare_obj(obj, expected) class InvalidSignalInit(AATest): tests = [ # init params expected exception (['send', '' , '/foo' ] , AppArmorBug), # empty signal (['' , 'int' , '/foo' ] , AppArmorBug), # empty access (['send', 'int' , '' ] , AppArmorBug), # empty peer ([' ', 'int' , '/foo' ] , AppArmorBug), # whitespace access (['send', ' ' , '/foo' ] , AppArmorBug), # whitespace signal (['send', 'int' , ' ' ] , AppArmorBug), # whitespace peer (['xyxy', 'int' , '/foo' ] , AppArmorException), # invalid access (['send', 'xyxy', '/foo' ] , AppArmorException), # invalid signal # XXX is 'invalid peer' possible at all? ([dict(), 'int' , '/foo' ] , AppArmorBug), # wrong type for access ([None , 'int' , '/foo' ] , AppArmorBug), # wrong type for access (['send', dict(), '/foo' ] , AppArmorBug), # wrong type for signal (['send', None , '/foo' ] , AppArmorBug), # wrong type for signal (['send', 'int' , dict() ] , AppArmorBug), # wrong type for peer (['send', 'int' , None ] , AppArmorBug), # wrong type for peer ] def _run_test(self, params, expected): with self.assertRaises(expected): SignalRule(params[0], params[1], params[2]) def test_missing_params_1(self): with self.assertRaises(TypeError): SignalRule() def test_missing_params_2(self): with self.assertRaises(TypeError): SignalRule('r') def test_missing_params_3(self): with self.assertRaises(TypeError): SignalRule('r', 'int') class InvalidSignalTest(AATest): def _check_invalid_rawrule(self, rawrule): obj = None self.assertFalse(SignalRule.match(rawrule)) with self.assertRaises(AppArmorException): obj = SignalRule(SignalRule.parse(rawrule)) self.assertIsNone(obj, 'SignalRule handed back an object unexpectedly') def test_invalid_signal_missing_comma(self): self._check_invalid_rawrule('signal') # missing comma def test_invalid_non_SignalRule(self): self._check_invalid_rawrule('dbus,') # not a signal rule def test_empty_data_1(self): obj = SignalRule('send', 'quit', '/foo') obj.access = '' # no access set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) def test_empty_data_2(self): obj = SignalRule('send', 'quit', '/foo') obj.signal = '' # no signal set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) def test_empty_data_3(self): obj = SignalRule('send', 'quit', '/foo') obj.peer = '' # no signal set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) class WriteSignalTestAATest(AATest): def _run_test(self, rawrule, expected): self.assertTrue(SignalRule.match(rawrule)) obj = SignalRule.parse(rawrule) clean = obj.get_clean() raw = obj.get_raw() self.assertEqual(expected.strip(), clean, 'unexpected clean rule') self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule') tests = [ # raw rule clean rule (' signal , # foo ' , 'signal, # foo'), (' audit signal send,' , 'audit signal send,'), (' audit signal (send ),' , 'audit signal send,'), (' audit signal (send , receive ),' , 'audit signal (receive send),'), (' deny signal send set=quit,# foo bar' , 'deny signal send set=quit, # foo bar'), (' deny signal send set=(quit), ' , 'deny signal send set=quit,'), (' deny signal send set=(int , quit),' , 'deny signal send set=(int quit),'), (' deny signal send set=(quit, int ),' , 'deny signal send set=(int quit),'), (' deny signal send ,# foo bar' , 'deny signal send, # foo bar'), (' allow signal set=int ,# foo bar' , 'allow signal set=int, # foo bar'), ('signal,' , 'signal,'), ('signal (receive),' , 'signal receive,'), ('signal (send),' , 'signal send,'), ('signal (send receive),' , 'signal (receive send),'), ('signal r,' , 'signal r,'), ('signal w,' , 'signal w,'), ('signal rw,' , 'signal rw,'), ('signal send set=("hup"),' , 'signal send set=hup,'), ('signal (receive) set=kill,' , 'signal receive set=kill,'), ('signal w set=(quit int),' , 'signal w set=(int quit),'), ('signal receive peer=foo,' , 'signal receive peer=foo,'), ('signal (send receive) peer=/usr/bin/bar,' , 'signal (receive send) peer=/usr/bin/bar,'), ('signal wr set=(pipe, usr1) peer=/sbin/baz,' , 'signal wr set=(pipe usr1) peer=/sbin/baz,'), ] def test_write_manually(self): obj = SignalRule('send', 'quit', '/foo', allow_keyword=True) expected = ' allow signal send set=quit peer=/foo,' self.assertEqual(expected, obj.get_clean(2), 'unexpected clean rule') self.assertEqual(expected, obj.get_raw(2), 'unexpected raw rule') class SignalCoveredTest(AATest): def _run_test(self, param, expected): obj = SignalRule.parse(self.rule) check_obj = SignalRule.parse(param) self.assertTrue(SignalRule.match(param)) self.assertEqual(obj.is_equal(check_obj), expected[0], 'Mismatch in is_equal, expected %s' % expected[0]) self.assertEqual(obj.is_equal(check_obj, True), expected[1], 'Mismatch in is_equal/strict, expected %s' % expected[1]) self.assertEqual(obj.is_covered(check_obj), expected[2], 'Mismatch in is_covered, expected %s' % expected[2]) self.assertEqual(obj.is_covered(check_obj, True, True), expected[3], 'Mismatch in is_covered/exact, expected %s' % expected[3]) class SignalCoveredTest_01(SignalCoveredTest): rule = 'signal send,' tests = [ # rule equal strict equal covered covered exact ('signal,' , [ False , False , False , False ]), ('signal send,' , [ True , True , True , True ]), ('signal send peer=unconfined,' , [ False , False , True , True ]), ('signal send, # comment' , [ True , False , True , True ]), ('allow signal send,' , [ True , False , True , True ]), ('signal send,' , [ True , False , True , True ]), ('signal send set=quit,' , [ False , False , True , True ]), ('signal send set=int,' , [ False , False , True , True ]), ('audit signal send,' , [ False , False , False , False ]), ('audit signal,' , [ False , False , False , False ]), ('signal receive,' , [ False , False , False , False ]), ('signal set=int,' , [ False , False , False , False ]), ('audit deny signal send,' , [ False , False , False , False ]), ('deny signal send,' , [ False , False , False , False ]), ] class SignalCoveredTest_02(SignalCoveredTest): rule = 'audit signal send,' tests = [ # rule equal strict equal covered covered exact ( 'signal send,' , [ False , False , True , False ]), ('audit signal send,' , [ True , True , True , True ]), ( 'signal send set=quit,' , [ False , False , True , False ]), ('audit signal send set=quit,' , [ False , False , True , True ]), ( 'signal,' , [ False , False , False , False ]), ('audit signal,' , [ False , False , False , False ]), ('signal receive,' , [ False , False , False , False ]), ] class SignalCoveredTest_03(SignalCoveredTest): rule = 'signal send set=quit,' tests = [ # rule equal strict equal covered covered exact ( 'signal send set=quit,' , [ True , True , True , True ]), ('allow signal send set=quit,' , [ True , False , True , True ]), ( 'signal send,' , [ False , False , False , False ]), ( 'signal,' , [ False , False , False , False ]), ( 'signal send set=int,' , [ False , False , False , False ]), ('audit signal,' , [ False , False , False , False ]), ('audit signal send set=quit,' , [ False , False , False , False ]), ('audit signal set=quit,' , [ False , False , False , False ]), ( 'signal send,' , [ False , False , False , False ]), ( 'signal,' , [ False , False , False , False ]), ] class SignalCoveredTest_04(SignalCoveredTest): rule = 'signal,' tests = [ # rule equal strict equal covered covered exact ( 'signal,' , [ True , True , True , True ]), ('allow signal,' , [ True , False , True , True ]), ( 'signal send,' , [ False , False , True , True ]), ( 'signal w set=quit,' , [ False , False , True , True ]), ( 'signal set=int,' , [ False , False , True , True ]), ( 'signal send set=quit,' , [ False , False , True , True ]), ('audit signal,' , [ False , False , False , False ]), ('deny signal,' , [ False , False , False , False ]), ] class SignalCoveredTest_05(SignalCoveredTest): rule = 'deny signal send,' tests = [ # rule equal strict equal covered covered exact ( 'deny signal send,' , [ True , True , True , True ]), ('audit deny signal send,' , [ False , False , False , False ]), ( 'signal send,' , [ False , False , False , False ]), # XXX should covered be true here? ( 'deny signal receive,' , [ False , False , False , False ]), ( 'deny signal,' , [ False , False , False , False ]), ] class SignalCoveredTest_06(SignalCoveredTest): rule = 'signal send peer=unconfined,' tests = [ # rule equal strict equal covered covered exact ('signal,' , [ False , False , False , False ]), ('signal send,' , [ False , False , False , False ]), ('signal send peer=unconfined,' , [ True , True , True , True ]), ('signal peer=unconfined,' , [ False , False , False , False ]), ('signal send, # comment' , [ False , False , False , False ]), ('allow signal send,' , [ False , False , False , False ]), ('allow signal send peer=unconfined,' , [ True , False , True , True ]), ('allow signal send peer=/foo/bar,' , [ False , False , False , False ]), ('allow signal send peer=/**,' , [ False , False , False , False ]), ('allow signal send peer=**,' , [ False , False , False , False ]), ('signal send,' , [ False , False , False , False ]), ('signal send peer=unconfined,' , [ True , False , True , True ]), ('signal send set=quit,' , [ False , False , False , False ]), ('signal send set=int peer=unconfined,',[ False , False , True , True ]), ('audit signal send peer=unconfined,' , [ False , False , False , False ]), ('audit signal,' , [ False , False , False , False ]), ('signal receive,' , [ False , False , False , False ]), ('signal set=int,' , [ False , False , False , False ]), ('audit deny signal send,' , [ False , False , False , False ]), ('deny signal send,' , [ False , False , False , False ]), ] class SignalCoveredTest_07(SignalCoveredTest): rule = 'signal send peer=/foo/bar,' tests = [ # rule equal strict equal covered covered exact ('signal,' , [ False , False , False , False ]), ('signal send,' , [ False , False , False , False ]), ('signal send peer=/foo/bar,' , [ True , True , True , True ]), ('signal send peer=/foo/*,' , [ False , False , False , False ]), ('signal send peer=/**,' , [ False , False , False , False ]), ('signal send peer=/what/*,' , [ False , False , False , False ]), ('signal peer=/foo/bar,' , [ False , False , False , False ]), ('signal send, # comment' , [ False , False , False , False ]), ('allow signal send,' , [ False , False , False , False ]), ('allow signal send peer=/foo/bar,' , [ True , False , True , True ]), ('signal send,' , [ False , False , False , False ]), ('signal send peer=/foo/bar,' , [ True , False , True , True ]), ('signal send peer=/what/ever,' , [ False , False , False , False ]), ('signal send set=quit,' , [ False , False , False , False ]), ('signal send set=int peer=/foo/bar,' , [ False , False , True , True ]), ('audit signal send peer=/foo/bar,' , [ False , False , False , False ]), ('audit signal,' , [ False , False , False , False ]), ('signal receive,' , [ False , False , False , False ]), ('signal set=int,' , [ False , False , False , False ]), ('audit deny signal send,' , [ False , False , False , False ]), ('deny signal send,' , [ False , False , False , False ]), ] class SignalCoveredTest_08(SignalCoveredTest): rule = 'signal send peer=**,' tests = [ # rule equal strict equal covered covered exact ('signal,' , [ False , False , False , False ]), ('signal send,' , [ False , False , False , False ]), ('signal send peer=/foo/bar,' , [ False , False , True , True ]), ('signal send peer=/foo/*,' , [ False , False , True , True ]), ('signal send peer=/**,' , [ False , False , True , True ]), ('signal send peer=/what/*,' , [ False , False , True , True ]), ('signal peer=/foo/bar,' , [ False , False , False , False ]), ('signal send, # comment' , [ False , False , False , False ]), ('allow signal send,' , [ False , False , False , False ]), ('allow signal send peer=/foo/bar,' , [ False , False , True , True ]), ('signal send,' , [ False , False , False , False ]), ('signal send peer=/foo/bar,' , [ False , False , True , True ]), ('signal send peer=/what/ever,' , [ False , False , True , True ]), ('signal send set=quit,' , [ False , False , False , False ]), ('signal send set=int peer=/foo/bar,' , [ False , False , True , True ]), ('audit signal send peer=/foo/bar,' , [ False , False , False , False ]), ('audit signal,' , [ False , False , False , False ]), ('signal receive,' , [ False , False , False , False ]), ('signal set=int,' , [ False , False , False , False ]), ('audit deny signal send,' , [ False , False , False , False ]), ('deny signal send,' , [ False , False , False , False ]), ] class SignalCoveredTest_09(SignalCoveredTest): rule = 'signal (send, receive) set=(int, quit),' tests = [ # rule equal strict equal covered covered exact ('signal,' , [ False , False , False , False ]), ('signal send,' , [ False , False , False , False ]), ('signal send set=int,' , [ False , False , True , True ]), ('signal receive set=quit,' , [ False , False , True , True ]), ('signal (receive,send) set=int,' , [ False , False , True , True ]), ('signal (receive,send) set=(int quit),',[True , False , True , True ]), ('signal send set=(quit int),' , [ False , False , True , True ]), ('signal send peer=/foo/bar,' , [ False , False , False , False ]), ('signal send peer=/foo/*,' , [ False , False , False , False ]), ('signal send peer=/**,' , [ False , False , False , False ]), ('signal send peer=/what/*,' , [ False , False , False , False ]), ('signal peer=/foo/bar,' , [ False , False , False , False ]), ('signal send, # comment' , [ False , False , False , False ]), ('allow signal send,' , [ False , False , False , False ]), ('allow signal send peer=/foo/bar,' , [ False , False , False , False ]), ('signal send,' , [ False , False , False , False ]), ('signal send peer=/foo/bar,' , [ False , False , False , False ]), ('signal send peer=/what/ever,' , [ False , False , False , False ]), ('signal send set=quit,' , [ False , False , True , True ]), ('signal send set=int peer=/foo/bar,' , [ False , False , True , True ]), ('audit signal send peer=/foo/bar,' , [ False , False , False , False ]), ('audit signal,' , [ False , False , False , False ]), ('signal receive,' , [ False , False , False , False ]), ('signal set=int,' , [ False , False , False , False ]), ('audit deny signal send,' , [ False , False , False , False ]), ('deny signal send,' , [ False , False , False , False ]), ] class SignalCoveredTest_Invalid(AATest): def test_borked_obj_is_covered_1(self): obj = SignalRule.parse('signal send peer=/foo,') testobj = SignalRule('send', 'quit', '/foo') testobj.access = '' with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_borked_obj_is_covered_2(self): obj = SignalRule.parse('signal send set=quit peer=/foo,') testobj = SignalRule('send', 'quit', '/foo') testobj.signal = '' with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_borked_obj_is_covered_3(self): obj = SignalRule.parse('signal send set=quit peer=/foo,') testobj = SignalRule('send', 'quit', '/foo') testobj.peer = '' with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_invalid_is_covered(self): obj = SignalRule.parse('signal send,') testobj = BaseRule() # different type with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_invalid_is_equal(self): obj = SignalRule.parse('signal send,') testobj = BaseRule() # different type with self.assertRaises(AppArmorBug): obj.is_equal(testobj) class SignalLogprofHeaderTest(AATest): tests = [ ('signal,', [ _('Access mode'), _('ALL'), _('Signal'), _('ALL'), _('Peer'), _('ALL'), ]), ('signal send,', [ _('Access mode'), 'send', _('Signal'), _('ALL'), _('Peer'), _('ALL'), ]), ('signal send set=quit,', [ _('Access mode'), 'send', _('Signal'), 'quit', _('Peer'), _('ALL'), ]), ('deny signal,', [_('Qualifier'), 'deny', _('Access mode'), _('ALL'), _('Signal'), _('ALL'), _('Peer'), _('ALL'), ]), ('allow signal send,', [_('Qualifier'), 'allow', _('Access mode'), 'send', _('Signal'), _('ALL'), _('Peer'), _('ALL'), ]), ('audit signal send set=quit,', [_('Qualifier'), 'audit', _('Access mode'), 'send', _('Signal'), 'quit', _('Peer'), _('ALL'), ]), ('audit deny signal send,', [_('Qualifier'), 'audit deny', _('Access mode'), 'send', _('Signal'), _('ALL'), _('Peer'), _('ALL'), ]), ('signal set=(int, quit),', [ _('Access mode'), _('ALL'), _('Signal'), 'int quit', _('Peer'), _('ALL'), ]), ('signal set=( quit, int),', [ _('Access mode'), _('ALL'), _('Signal'), 'int quit', _('Peer'), _('ALL'), ]), ('signal (send, receive) set=( quit, int) peer=/foo,', [ _('Access mode'), 'receive send', _('Signal'), 'int quit', _('Peer'), '/foo', ]), ] def _run_test(self, params, expected): obj = SignalRule._parse(params) self.assertEqual(obj.logprof_header(), expected) ## --- tests for SignalRuleset --- # class SignalRulesTest(AATest): def test_empty_ruleset(self): ruleset = SignalRuleset() ruleset_2 = SignalRuleset() self.assertEqual([], ruleset.get_raw(2)) self.assertEqual([], ruleset.get_clean(2)) self.assertEqual([], ruleset_2.get_raw(2)) self.assertEqual([], ruleset_2.get_clean(2)) def test_ruleset_1(self): ruleset = SignalRuleset() rules = [ 'signal set=int,', 'signal send,', ] expected_raw = [ 'signal set=int,', 'signal send,', '', ] expected_clean = [ 'signal send,', 'signal set=int,', '', ] for rule in rules: ruleset.add(SignalRule.parse(rule)) self.assertEqual(expected_raw, ruleset.get_raw()) self.assertEqual(expected_clean, ruleset.get_clean()) def test_ruleset_2(self): ruleset = SignalRuleset() rules = [ 'signal send set=int,', 'allow signal send,', 'deny signal set=quit, # example comment', ] expected_raw = [ ' signal send set=int,', ' allow signal send,', ' deny signal set=quit, # example comment', '', ] expected_clean = [ ' deny signal set=quit, # example comment', '', ' allow signal send,', ' signal send set=int,', '', ] for rule in rules: ruleset.add(SignalRule.parse(rule)) self.assertEqual(expected_raw, ruleset.get_raw(1)) self.assertEqual(expected_clean, ruleset.get_clean(1)) class SignalGlobTestAATest(AATest): def setUp(self): self.maxDiff = None self.ruleset = SignalRuleset() def test_glob_1(self): self.assertEqual(self.ruleset.get_glob('signal send,'), 'signal,') # not supported or used yet # def test_glob_2(self): # self.assertEqual(self.ruleset.get_glob('signal send raw,'), 'signal send,') def test_glob_ext(self): with self.assertRaises(NotImplementedError): # get_glob_ext is not available for signal rules self.ruleset.get_glob_ext('signal send set=int,') #class SignalDeleteTestAATest(AATest): # pass setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-rlimit.py0000644000175000017500000005441413502024172016163 0ustar jjjj#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import unittest from collections import namedtuple from common_test import AATest, setup_all_loops from apparmor.rule.rlimit import RlimitRule, RlimitRuleset, split_unit from apparmor.rule import BaseRule from apparmor.common import AppArmorException, AppArmorBug #from apparmor.logparser import ReadLog from apparmor.translations import init_translation _ = init_translation() exp = namedtuple('exp', ['audit', 'allow_keyword', 'deny', 'comment', 'rlimit', 'value', 'all_values']) # --- tests for single RlimitRule --- # class RlimitTest(AATest): def _compare_obj(self, obj, expected): self.assertEqual(expected.allow_keyword, obj.allow_keyword) self.assertEqual(expected.audit, obj.audit) self.assertEqual(expected.rlimit, obj.rlimit) self.assertEqual(expected.value, obj.value) self.assertEqual(expected.all_values, obj.all_values) self.assertEqual(expected.deny, obj.deny) self.assertEqual(expected.comment, obj.comment) class RlimitTestParse(RlimitTest): tests = [ # rawrule audit allow deny comment rlimit value all/infinity? ('set rlimit as <= 2047MB,' , exp(False, False, False, '' , 'as' , '2047MB' , False)), ('set rlimit as <= 2047 MB,' , exp(False, False, False, '' , 'as' , '2047 MB' , False)), ('set rlimit cpu <= 1024,' , exp(False, False, False, '' , 'cpu' , '1024' , False)), ('set rlimit stack <= 1024GB,' , exp(False, False, False, '' , 'stack' , '1024GB' , False)), ('set rlimit stack <= 1024 GB,' , exp(False, False, False, '' , 'stack' , '1024 GB' , False)), ('set rlimit rtprio <= 10, # comment' , exp(False, False, False, ' # comment' , 'rtprio' , '10' , False)), ('set rlimit core <= 44444KB,' , exp(False, False, False, '' , 'core' , '44444KB' , False)), ('set rlimit core <= 44444 KB,' , exp(False, False, False, '' , 'core' , '44444 KB' , False)), ('set rlimit rttime <= 60ms,' , exp(False, False, False, '' , 'rttime' , '60ms' , False)), ('set rlimit cpu <= infinity,' , exp(False, False, False, '' , 'cpu' , None , True )), ('set rlimit nofile <= 256,' , exp(False, False, False, '' , 'nofile' , '256' , False)), ('set rlimit data <= 4095KB,' , exp(False, False, False, '' , 'data' , '4095KB' , False)), ('set rlimit cpu <= 12, # cmt' , exp(False, False, False, ' # cmt' , 'cpu' , '12' , False)), ('set rlimit ofile <= 1234,' , exp(False, False, False, '' , 'ofile' , '1234' , False)), ('set rlimit msgqueue <= 4444,' , exp(False, False, False, '' , 'msgqueue' , '4444' , False)), ('set rlimit nice <= -10,' , exp(False, False, False, '' , 'nice' , '-10' , False)), ('set rlimit rttime <= 60minutes,' , exp(False, False, False, '' , 'rttime' , '60minutes' , False)), ('set rlimit fsize <= 1023MB,' , exp(False, False, False, '' , 'fsize' , '1023MB' , False)), ('set rlimit nproc <= 1,' , exp(False, False, False, '' , 'nproc' , '1' , False)), ('set rlimit rss <= infinity, # cmt' , exp(False, False, False, ' # cmt' , 'rss' , None , True )), ('set rlimit memlock <= 10240,' , exp(False, False, False, '' , 'memlock' , '10240' , False)), ('set rlimit sigpending <= 42,' , exp(False, False, False, '' , 'sigpending' , '42' , False)), ] def _run_test(self, rawrule, expected): self.assertTrue(RlimitRule.match(rawrule)) obj = RlimitRule.parse(rawrule) self.assertEqual(rawrule.strip(), obj.raw_rule) self._compare_obj(obj, expected) class RlimitTestParseInvalid(RlimitTest): tests = [ ('set rlimit,' , AppArmorException), # missing parts ('set rlimit <= 5,' , AppArmorException), ('set rlimit cpu <= ,' , AppArmorException), ('set rlimit cpu <= "",' , AppArmorBug), # evil quoting trick ('set rlimit foo <= 5,' , AppArmorException), # unknown rlimit ('set rlimit rttime <= 60m,' , AppArmorException), # 'm' could mean 'ms' or 'minutes' ('set rlimit cpu <= 20ms,' , AppArmorException), # cpu doesn't support 'ms'... ('set rlimit cpu <= 20us,' , AppArmorException), # ... or 'us' ('set rlimit nice <= 20MB,' , AppArmorException), # invalid unit for this rlimit type ('set rlimit cpu <= 20MB,' , AppArmorException), ('set rlimit data <= 20seconds,' , AppArmorException), ('set rlimit locks <= 20seconds,' , AppArmorException), ] def _run_test(self, rawrule, expected): #self.assertFalse(RlimitRule.match(rawrule)) # the main regex isn't very strict with self.assertRaises(expected): RlimitRule.parse(rawrule) class RlimitTestParseFromLog(RlimitTest): pass # def test_net_from_log(self): # parser = ReadLog('', '', '', '') # event = 'type=AVC ...' # parsed_event = parser.parse_event(event) # self.assertEqual(parsed_event, { # ... # }) # obj = RlimitRule(RlimitRule.ALL, parsed_event['name2'], log_event=parsed_event) # # audit allow deny comment rlimit value all? # expected = exp(False, False, False, '' , None, '/foo/rename', False) # self._compare_obj(obj, expected) # self.assertEqual(obj.get_raw(1), ' rlimit -> /foo/rename,') class RlimitFromInit(RlimitTest): tests = [ # RlimitRule object audit allow deny comment rlimit value all/infinity? (RlimitRule('as', '2047MB') , exp(False, False, False, '' , 'as' , '2047MB' , False)), (RlimitRule('as', '2047 MB') , exp(False, False, False, '' , 'as' , '2047 MB' , False)), (RlimitRule('cpu', '1024') , exp(False, False, False, '' , 'cpu' , '1024' , False)), (RlimitRule('rttime', '60minutes') , exp(False, False, False, '' , 'rttime' , '60minutes', False)), (RlimitRule('nice', '-10') , exp(False, False, False, '' , 'nice' , '-10' , False)), (RlimitRule('rss', RlimitRule.ALL) , exp(False, False, False, '' , 'rss' , None , True )), ] def _run_test(self, obj, expected): self._compare_obj(obj, expected) class InvalidRlimitInit(AATest): tests = [ # init params expected exception (['as' , '' ] , AppArmorBug), # empty value (['' , '1024' ] , AppArmorException), # empty rlimit ([' ', '1024' ] , AppArmorException), # whitespace rlimit (['as' , ' ' ] , AppArmorBug), # whitespace value (['xyxy', '1024' ] , AppArmorException), # invalid rlimit ([dict(), '1024' ] , AppArmorBug), # wrong type for rlimit ([None , '1024' ] , AppArmorBug), # wrong type for rlimit (['as' , dict() ] , AppArmorBug), # wrong type for value (['as' , None ] , AppArmorBug), # wrong type for value (['cpu' , '100xy2' ] , AppArmorException), # invalid unit ] def _run_test(self, params, expected): with self.assertRaises(expected): RlimitRule(params[0], params[1]) def test_missing_params_1(self): with self.assertRaises(TypeError): RlimitRule() def test_missing_params_2(self): with self.assertRaises(TypeError): RlimitRule('as') def test_allow_keyword(self): with self.assertRaises(AppArmorBug): RlimitRule('as', '1024MB', allow_keyword=True) def test_deny_keyword(self): with self.assertRaises(AppArmorBug): RlimitRule('as', '1024MB', deny=True) def test_audit_keyword(self): with self.assertRaises(AppArmorBug): RlimitRule('as', '1024MB', audit=True) class InvalidRlimitTest(AATest): def _check_invalid_rawrule(self, rawrule): obj = None self.assertFalse(RlimitRule.match(rawrule)) with self.assertRaises(AppArmorException): obj = RlimitRule(RlimitRule.parse(rawrule)) self.assertIsNone(obj, 'RlimitRule handed back an object unexpectedly') def test_invalid_net_missing_comma(self): self._check_invalid_rawrule('rlimit') # missing comma def test_invalid_net_non_RlimitRule(self): self._check_invalid_rawrule('dbus,') # not a rlimit rule def test_empty_net_data_1(self): obj = RlimitRule('as', '1024MB') obj.rlimit = '' # no rlimit set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) def test_empty_net_data_2(self): obj = RlimitRule('as', '1024MB') obj.value = '' # no value set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) class WriteRlimitTest(AATest): tests = [ # raw rule clean rule (' set rlimit cpu <= 1024 , # foo ' , 'set rlimit cpu <= 1024, # foo'), (' set rlimit stack <= 1024GB ,' , 'set rlimit stack <= 1024GB,'), (' set rlimit rttime <= 100ms , # foo bar' , 'set rlimit rttime <= 100ms, # foo bar'), (' set rlimit cpu <= infinity , ' , 'set rlimit cpu <= infinity,'), (' set rlimit msgqueue <= 4444 , ' , 'set rlimit msgqueue <= 4444,'), (' set rlimit nice <= 5 , # foo bar' , 'set rlimit nice <= 5, # foo bar'), (' set rlimit nice <= -5 , # cmt' , 'set rlimit nice <= -5, # cmt'), ] def _run_test(self, rawrule, expected): self.assertTrue(RlimitRule.match(rawrule)) obj = RlimitRule.parse(rawrule) clean = obj.get_clean() raw = obj.get_raw() self.assertEqual(expected.strip(), clean, 'unexpected clean rule') self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule') def test_write_manually(self): obj = RlimitRule('as', '1024MB') expected = ' set rlimit as <= 1024MB,' self.assertEqual(expected, obj.get_clean(2), 'unexpected clean rule') self.assertEqual(expected, obj.get_raw(2), 'unexpected raw rule') class RlimitCoveredTest(AATest): def _run_test(self, param, expected): obj = RlimitRule.parse(self.rule) check_obj = RlimitRule.parse(param) self.assertTrue(RlimitRule.match(param)) self.assertEqual(obj.is_equal(check_obj), expected[0], 'Mismatch in is_equal, expected %s' % expected[0]) self.assertEqual(obj.is_equal(check_obj, True), expected[1], 'Mismatch in is_equal/strict, expected %s' % expected[1]) self.assertEqual(obj.is_covered(check_obj), expected[2], 'Mismatch in is_covered, expected %s' % expected[2]) self.assertEqual(obj.is_covered(check_obj, True, True), expected[3], 'Mismatch in is_covered/exact, expected %s' % expected[3]) class RlimitCoveredTest_01(RlimitCoveredTest): rule = 'set rlimit cpu <= 150,' tests = [ # rule equal strict equal covered covered exact ('set rlimit as <= 100MB,' , [ False , False , False , False ]), ('set rlimit rttime <= 150,' , [ False , False , False , False ]), ('set rlimit cpu <= 100,' , [ False , False , True , True ]), ('set rlimit cpu <= 150,' , [ True , True , True , True ]), ('set rlimit cpu <= 300,' , [ False , False , False , False ]), ('set rlimit cpu <= 10seconds,' , [ False , False , True , True ]), ('set rlimit cpu <= 150seconds,', [ True , False , True , True ]), ('set rlimit cpu <= 300seconds,', [ False , False , False , False ]), ('set rlimit cpu <= 1minutes,' , [ False , False , True , True ]), ('set rlimit cpu <= 1min,' , [ False , False , True , True ]), ('set rlimit cpu <= 3minutes,' , [ False , False , False , False ]), ('set rlimit cpu <= 1hour,' , [ False , False , False , False ]), ('set rlimit cpu <= 2 days,' , [ False , False , False , False ]), ('set rlimit cpu <= 1 week,' , [ False , False , False , False ]), ] class RlimitCoveredTest_02(RlimitCoveredTest): rule = 'set rlimit data <= 4MB,' tests = [ # rule equal strict equal covered covered exact ('set rlimit data <= 100,' , [ False , False , True , True ]), ('set rlimit data <= 2KB,' , [ False , False , True , True ]), ('set rlimit data <= 2MB,' , [ False , False , True , True ]), ('set rlimit data <= 4194304,' , [ True , False , True , True ]), ('set rlimit data <= 4096KB,' , [ True , False , True , True ]), ('set rlimit data <= 4MB,' , [ True , True , True , True ]), ('set rlimit data <= 4 MB,' , [ True , False , True , True ]), ('set rlimit data <= 6MB,' , [ False , False , False , False ]), ('set rlimit data <= 6 MB,' , [ False , False , False , False ]), ('set rlimit data <= 1GB,' , [ False , False , False , False ]), ] class RlimitCoveredTest_03(RlimitCoveredTest): rule = 'set rlimit nice <= -1,' tests = [ # rule equal strict equal covered covered exact ('set rlimit nice <= 5,' , [ False , False , True , True ]), ('set rlimit nice <= 0,' , [ False , False , True , True ]), ('set rlimit nice <= -1,' , [ True , True , True , True ]), ('set rlimit nice <= -3,' , [ False , False , False , False ]), ] class RlimitCoveredTest_04(RlimitCoveredTest): rule = 'set rlimit locks <= 42,' tests = [ # rule equal strict equal covered covered exact ('set rlimit locks <= 20,' , [ False , False , True , True ]), ('set rlimit locks <= 40,' , [ False , False , True , True ]), ('set rlimit locks <= 42,' , [ True , True , True , True ]), ('set rlimit locks <= 60,' , [ False , False , False , False ]), ('set rlimit locks <= infinity,', [ False , False , False , False ]), ] class RlimitCoveredTest_05(RlimitCoveredTest): rule = 'set rlimit locks <= infinity,' tests = [ # rule equal strict equal covered covered exact ('set rlimit locks <= 20,' , [ False , False , True , True ]), ('set rlimit cpu <= 40,' , [ False , False , False , False ]), ('set rlimit locks <= infinity,', [ True , True , True , True ]), ] class RlimitCoveredTest_Invalid(AATest): def test_borked_obj_is_covered_1(self): obj = RlimitRule.parse('set rlimit cpu <= 1024,') testobj = RlimitRule('cpu', '1024') testobj.rlimit = '' with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_borked_obj_is_covered_2(self): obj = RlimitRule.parse('set rlimit cpu <= 1024,') testobj = RlimitRule('cpu', '1024') testobj.value = '' with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_invalid_is_covered(self): obj = RlimitRule.parse('set rlimit cpu <= 1024,') testobj = BaseRule() # different type with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_invalid_is_equal(self): obj = RlimitRule.parse('set rlimit cpu <= 1024,') testobj = BaseRule() # different type with self.assertRaises(AppArmorBug): obj.is_equal(testobj) class RlimitLogprofHeaderTest(AATest): tests = [ ('set rlimit cpu <= infinity,', [_('Rlimit'), 'cpu', _('Value'), 'infinity', ]), ('set rlimit as <= 200MB,', [_('Rlimit'), 'as', _('Value'), '200MB', ]), ('set rlimit rttime <= 200ms,', [_('Rlimit'), 'rttime', _('Value'), '200ms', ]), ('set rlimit nproc <= 1,', [_('Rlimit'), 'nproc', _('Value'), '1', ]), ] def _run_test(self, params, expected): obj = RlimitRule._parse(params) self.assertEqual(obj.logprof_header(), expected) # --- tests for RlimitRuleset --- # class RlimitRulesTest(AATest): def test_empty_ruleset(self): ruleset = RlimitRuleset() ruleset_2 = RlimitRuleset() self.assertEqual([], ruleset.get_raw(2)) self.assertEqual([], ruleset.get_clean(2)) self.assertEqual([], ruleset_2.get_raw(2)) self.assertEqual([], ruleset_2.get_clean(2)) def test_ruleset_1(self): ruleset = RlimitRuleset() rules = [ ' set rlimit cpu <= 100,', ' set rlimit as <= 50MB,', ] expected_raw = [ 'set rlimit cpu <= 100,', 'set rlimit as <= 50MB,', '', ] expected_clean = [ 'set rlimit as <= 50MB,', 'set rlimit cpu <= 100,', '', ] for rule in rules: ruleset.add(RlimitRule.parse(rule)) self.assertEqual(expected_raw, ruleset.get_raw()) self.assertEqual(expected_clean, ruleset.get_clean()) class RlimitGlobTestAATest(AATest): def setUp(self): self.ruleset = RlimitRuleset() def test_glob_1(self): with self.assertRaises(AppArmorBug): self.ruleset.get_glob('set rlimit cpu <= 100,') # not supported or used yet, glob behaviour not decided yet # def test_glob_2(self): # self.assertEqual(self.ruleset.get_glob('rlimit /foo -> /bar,'), 'rlimit -> /bar,') def test_glob_ext(self): with self.assertRaises(NotImplementedError): # get_glob_ext is not available for rlimit rules self.ruleset.get_glob_ext('set rlimit cpu <= 100,') class RlimitDeleteTestAATest(AATest): # no de-duplication tests for rlimit - de-duplication consists of is_covered() (which we already test) and # code from BaseRuleset (which is already tested in the capability, network and change_profile tests). # Therefore no need to test it once more ;-) pass # --- other tests --- # class RlimitSplit_unitTest(AATest): tests = [ ('40MB' , ( 40, 'MB',)), ('40 MB' , ( 40, 'MB',)), ('40' , ( 40, '', )), ] def _run_test(self, params, expected): self.assertEqual(split_unit(params), expected) def test_invalid_split_unit(self): with self.assertRaises(AppArmorBug): split_unit('MB') class RlimitSize_to_intTest(AATest): def AASetup(self): self.obj = RlimitRule('cpu', '1') tests = [ ('40GB' , 40 * 1024 * 1024 * 1024), ('40MB' , 41943040), ('40KB' , 40960), ('40' , 40), ] def _run_test(self, params, expected): self.assertEqual(self.obj.size_to_int(params), expected) def test_invalid_size_to_int_01(self): with self.assertRaises(AppArmorException): self.obj.size_to_int('20mice') class RlimitTime_to_intTest(AATest): def AASetup(self): self.obj = RlimitRule('cpu', '1') tests = [ ('40' , 0.00004), ('30us' , 0.00003), ('40ms' , 0.04), ('40seconds', 40), ('2minutes' , 2*60), ('2hours' , 2*60*60), ('1 day' , 1*60*60*24), ('2 weeks' , 2*60*60*24*7), ] def _run_test(self, params, expected): self.assertEqual(self.obj.time_to_int(params, 'us'), expected) def test_with_seconds_as_default(self): self.assertEqual(self.obj.time_to_int('40', 'seconds'), 40) def test_with_ms_as_default(self): self.assertEqual(self.obj.time_to_int('40', 'ms'), 0.04) def test_with_us_as_default(self): self.assertEqual(self.obj.time_to_int('30', 'us'), 0.00003) def test_invalid_time_to_int(self): with self.assertRaises(AppArmorException): self.obj.time_to_int('20mice', 'seconds') setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-common.py0000644000175000017500000000160413502024172016144 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import unittest from common_test import AATest, setup_all_loops from apparmor.common import type_is_str class TestIs_str_type(AATest): tests = [ ('foo', True), (u'foo', True), (42, False), (True, False), ([], False), ] def _run_test(self, params, expected): self.assertEqual(type_is_str(params), expected) setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-config.py0000755000175000017500000000410313502024172016121 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import unittest import apparmor.config as config class Test(unittest.TestCase): def test_IniConfig(self): ini_config = config.Config('ini') ini_config.CONF_DIR = '.' conf = ini_config.read_config('logprof.conf') logprof_sections = ['settings', 'repository', 'qualifiers', 'required_hats', 'defaulthat', 'globs'] logprof_sections_options = ['profiledir', 'inactive_profiledir', 'logfiles', 'parser', 'ldd', 'logger', 'default_owner_prompt', 'custom_includes'] logprof_settings_parser = '../../parser/apparmor_parser' self.assertEqual(conf.sections(), logprof_sections) self.assertEqual(conf.options('settings'), logprof_sections_options) self.assertEqual(conf['settings']['parser'], logprof_settings_parser) def test_ShellConfig(self): shell_config = config.Config('shell') shell_config.CONF_DIR = '.' conf = shell_config.read_config('easyprof.conf') easyprof_sections = ['POLICYGROUPS_DIR', 'TEMPLATES_DIR'] easyprof_Policygroup = './policygroups' easyprof_Templates = './templates' self.assertEqual(sorted(list(conf[''].keys())), sorted(easyprof_sections)) self.assertEqual(conf['']['POLICYGROUPS_DIR'], easyprof_Policygroup) self.assertEqual(conf['']['TEMPLATES_DIR'], easyprof_Templates) if __name__ == "__main__": #import sys;sys.argv = ['', 'Test.testConfig'] unittest.main() apparmor-2.13.3/utils/test/runtests-py2.sh0000755000175000017500000000010313502024172016254 0ustar jjjj#!/bin/sh RUNTESTS_PY__PYTHON_BINARY=python2 . ./runtests-py3.sh apparmor-2.13.3/utils/test/cleanprof_test.in0000644000175000017500000000266213502024172016672 0ustar jjjj# A simple test comment which will persist #include alias /foo -> /bar , abi , /usr/bin/a/simple/cleanprof/test/profile { # Just for the heck of it, this comment wont see the day of light #include capability sys_admin, audit capability, change_profile -> /bin/foo, change_profile, network inet stream, abi "abi/4.20" , network stream, #Below rule comes from abstractions/base allow /usr/share/X11/locale/** r, allow /home/*/** r, ptrace tracedby peer=/bin/strace, ptrace tracedby, unix (receive) type=dgram, dbus send bus=session, dbus send bus=session peer=(label=foo), set rlimit nofile <= 256, set rlimit nofile <= 64, signal set=(hup int quit ill trap abrt) set=(bus,fpe,,,kill,usr1) set=segv set=usr2 set=pipe set=alrm set=term set=stkflt set=chld, signal set=(hup int quit), ^foo { /etc/fstab r, capability dac_override, } ^foo, # hat declarations are obsolete and will be removed when aa-cleanprof or aa-logprof writes the profile link subset /alpha/beta -> /tmp/**, allow /home/foo/bar r, allow /home/foo/** w, } /usr/bin/other/cleanprof/test/profile { # This one shouldn't be affected by the processing # However this comment will be wiped, need to change that allow /home/*/** rw, allow /home/foo/bar r, } apparmor-2.13.3/utils/test/minitools_test.py0000755000175000017500000002147413502024172016765 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import os import shutil import subprocess import sys import unittest from common_test import AATest, setup_all_loops, setup_aa import apparmor.aa as apparmor from common_test import read_file python_interpreter = 'python' if sys.version_info >= (3, 0): python_interpreter = 'python3' class MinitoolsTest(AATest): def AASetup(self): self.createTmpdir() #copy the local profiles to the test directory #Should be the set of cleanprofile self.profile_dir = '%s/profiles' % self.tmpdir shutil.copytree('../../profiles/apparmor.d/', self.profile_dir, symlinks=True) apparmor.profile_dir = self.profile_dir # Path for the program self.test_path = '/usr/sbin/winbindd' # Path for the target file containing profile self.local_profilename = '%s/usr.sbin.winbindd' % self.profile_dir def test_audit(self): # Set test profile to audit mode and check if it was correctly set str(subprocess.check_output('%s ./../aa-audit --no-reload -d %s %s' % (python_interpreter, self.profile_dir, self.test_path), shell=True)) self.assertEqual(apparmor.get_profile_flags(self.local_profilename, self.test_path), 'audit', 'Audit flag could not be set in profile %s' % self.local_profilename) # Remove audit mode from test profile and check if it was correctly removed subprocess.check_output('%s ./../aa-audit --no-reload -d %s -r %s' % (python_interpreter, self.profile_dir, self.test_path), shell=True) self.assertEqual(apparmor.get_profile_flags(self.local_profilename, self.test_path), None, 'Audit flag could not be removed in profile %s' % self.local_profilename) def test_complain(self): # Set test profile to complain mode and check if it was correctly set subprocess.check_output('%s ./../aa-complain --no-reload -d %s %s' % (python_interpreter, self.profile_dir, self.test_path), shell=True) # "manually" create a force-complain symlink (will be deleted by aa-enforce later) force_complain_dir = '%s/force-complain' % self.profile_dir if not os.path.isdir(force_complain_dir): os.mkdir(force_complain_dir) os.symlink(self.local_profilename, '%s/%s' % (force_complain_dir, os.path.basename(self.local_profilename))) self.assertEqual(os.path.islink('%s/%s' % (force_complain_dir, os.path.basename(self.local_profilename))), True, 'Failed to create a symlink for %s in force-complain' % self.local_profilename) self.assertEqual(apparmor.get_profile_flags(self.local_profilename, self.test_path), 'complain', 'Complain flag could not be set in profile %s'%self.local_profilename) # Set test profile to enforce mode and check if it was correctly set subprocess.check_output('%s ./../aa-enforce --no-reload -d %s %s'%(python_interpreter, self.profile_dir, self.test_path), shell=True) self.assertEqual(os.path.islink('%s/%s' % (force_complain_dir, os.path.basename(self.local_profilename))), False, 'Failed to remove symlink for %s from force-complain'%self.local_profilename) self.assertEqual(os.path.islink('%s/disable/%s' % (self.profile_dir, os.path.basename(self.local_profilename))), False, 'Failed to remove symlink for %s from disable'%self.local_profilename) self.assertEqual(apparmor.get_profile_flags(self.local_profilename, self.test_path), None, 'Complain flag could not be removed in profile %s'%self.local_profilename) # Set audit flag and then complain flag in a profile subprocess.check_output('%s ./../aa-audit --no-reload -d %s %s'%(python_interpreter, self.profile_dir, self.test_path), shell=True) subprocess.check_output('%s ./../aa-complain --no-reload -d %s %s'%(python_interpreter, self.profile_dir, self.test_path), shell=True) # "manually" create a force-complain symlink (will be deleted by aa-enforce later) os.symlink(self.local_profilename, '%s/%s'% (force_complain_dir, os.path.basename(self.local_profilename))) self.assertEqual(os.path.islink('%s/%s' % (force_complain_dir, os.path.basename(self.local_profilename))), True, 'Failed to create a symlink for %s in force-complain'%self.local_profilename) self.assertEqual(apparmor.get_profile_flags(self.local_profilename, self.test_path), 'audit, complain', 'Complain flag could not be set in profile %s'%self.local_profilename) #Remove complain flag first i.e. set to enforce mode subprocess.check_output('%s ./../aa-enforce --no-reload -d %s %s'%(python_interpreter, self.profile_dir, self.test_path), shell=True) self.assertEqual(os.path.islink('%s/%s' % (force_complain_dir, os.path.basename(self.local_profilename))), False, 'Failed to remove symlink for %s from force-complain'%self.local_profilename) self.assertEqual(os.path.islink('%s/disable/%s' % (self.profile_dir, os.path.basename(self.local_profilename))), False, 'Failed to remove symlink for %s from disable'%self.local_profilename) self.assertEqual(apparmor.get_profile_flags(self.local_profilename, self.test_path), 'audit', 'Complain flag could not be removed in profile %s'%self.local_profilename) #Remove audit flag subprocess.check_output('%s ./../aa-audit --no-reload -d %s -r %s'%(python_interpreter, self.profile_dir, self.test_path), shell=True) def test_enforce(self): # Set test profile to enforce mode and check if it was correctly set subprocess.check_output('%s ./../aa-enforce --no-reload -d %s %s'%(python_interpreter, self.profile_dir, self.test_path), shell=True) self.assertEqual(os.path.islink('%s/force-complain/%s' % (self.profile_dir, os.path.basename(self.local_profilename))), False, 'Failed to remove symlink for %s from force-complain'%self.local_profilename) self.assertEqual(os.path.islink('%s/disable/%s' % (self.profile_dir, os.path.basename(self.local_profilename))), False, 'Failed to remove symlink for %s from disable'%self.local_profilename) self.assertEqual(apparmor.get_profile_flags(self.local_profilename, self.test_path), None, 'Complain flag could not be removed in profile %s'%self.local_profilename) def test_disable(self): # Disable the test profile and check if it was correctly disabled subprocess.check_output('%s ./../aa-disable --no-reload -d %s %s'%(python_interpreter, self.profile_dir, self.test_path), shell=True) self.assertEqual(os.path.islink('%s/disable/%s' % (self.profile_dir, os.path.basename(self.local_profilename))), True, 'Failed to create a symlink for %s in disable' % self.local_profilename) def test_autodep(self): pass def test_unconfined(self): output = subprocess.check_output('%s ./../aa-unconfined'%python_interpreter, shell=True) output_force = subprocess.check_output('%s ./../aa-unconfined --paranoid'%python_interpreter, shell=True) self.assertIsNot(output, '', 'Failed to run aa-unconfined') self.assertIsNot(output_force, '', 'Failed to run aa-unconfined in paranoid mode') def test_cleanprof(self): input_file = 'cleanprof_test.in' output_file = 'cleanprof_test.out' #We position the local testfile shutil.copy('./%s'%input_file, self.profile_dir) #Our silly test program whose profile we wish to clean cleanprof_test = '/usr/bin/a/simple/cleanprof/test/profile' subprocess.check_output('%s ./../aa-cleanprof --no-reload -d %s -s %s' % (python_interpreter, self.profile_dir, cleanprof_test), shell=True) #Strip off the first line (#modified line) subprocess.check_output('sed -i 1d %s/%s' % (self.profile_dir, input_file), shell=True) exp_content = read_file('./%s' % output_file) real_content = read_file('%s/%s' % (self.profile_dir, input_file)) self.maxDiff = None self.assertEqual(exp_content, real_content, 'Failed to cleanup profile properly') setup_aa(apparmor) setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-unix_parse.py0000644000175000017500000000250313502024172017030 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import apparmor.aa as aa import unittest from common_test import AAParseTest, setup_regex_tests, setup_aa class AAParseUnixTest(AAParseTest): def setUp(self): self.parse_function = aa.parse_unix_rule tests = [ ('unix,', 'unix base keyword'), ('unix r,', 'unix r rule'), ('unix w,', 'unix w rule'), ('unix rw,', 'unix rw rule'), ('unix send,', 'unix send rule'), ('unix receive,', 'unix receive rule'), ('unix (r),', 'unix (r) rule'), ('unix (w),', 'unix (w) rule'), ('unix (rw),', 'unix (rw) rule'), ('unix (send),', 'unix (send) rule'), ('unix (receive),', 'unix (receive) rule'), ('unix (connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/.X11-unix/X[0-9]*"),', 'complex unix rule'), ] setup_aa(aa) if __name__ == '__main__': setup_regex_tests(AAParseUnixTest) unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-aa-decode.py0000755000175000017500000002121113502024172016455 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2011-2012 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import os import signal import subprocess import tempfile import unittest # The locationg of the aa-decode utility can be overridden by setting # the APPARMOR_DECODE environment variable; this is useful for running # these tests in an installed environment aadecode_bin = "../aa-decode" # http://www.chiark.greenend.org.uk/ucgi/~cjwatson/blosxom/2009-07-02-python-sigpipe.html # This is needed so that the subprocesses that produce endless output # actually quit when the reader goes away. def subprocess_setup(): # Python installs a SIGPIPE handler by default. This is usually not what # non-Python subprocesses expect. signal.signal(signal.SIGPIPE, signal.SIG_DFL) def cmd(command, input = None, stderr = subprocess.STDOUT, stdout = subprocess.PIPE, stdin = None, timeout = None): '''Try to execute given command (array) and return its stdout, or return a textual error if it failed.''' try: sp = subprocess.Popen(command, stdin=stdin, stdout=stdout, stderr=stderr, close_fds=True, preexec_fn=subprocess_setup) except OSError as e: return [127, str(e)] out, outerr = sp.communicate(input) # Handle redirection of stdout if out == None: out = b'' # Handle redirection of stderr if outerr == None: outerr = b'' return [sp.returncode, out.decode('utf-8') + outerr.decode('utf-8')] def mkstemp_fill(contents, suffix='', prefix='tst-aadecode-', dir=None): '''As tempfile.mkstemp does, return a (file, name) pair, but with prefilled contents.''' handle, name = tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=dir) os.close(handle) handle = open(name, "w+") handle.write(contents) handle.flush() handle.seek(0) return handle, name class AADecodeTest(unittest.TestCase): def setUp(self): self.tmpfile = None def tearDown(self): if self.tmpfile and os.path.exists(self.tmpfile): os.remove(self.tmpfile) def test_help(self): '''Test --help argument''' expected = 0 rc, report = cmd([aadecode_bin, "--help"]) result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEqual(expected, rc, result + report) def _run_file_test(self, content, expected_list): '''test case helper function; takes log content and a list of expected strings as arguments''' expected = 0 (f, self.tmpfile) = mkstemp_fill(content) rc, report = cmd([aadecode_bin], stdin=f) result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEqual(expected, rc, result + report) for expected_string in expected_list: result = 'could not find expected %s in output:\n' % (expected_string) self.assertIn(expected_string, report, result + report) f.close() def test_simple_decode(self): '''Test simple decode on command line''' expected = 0 expected_output = 'Decoded: /tmp/foo bar' test_code = '2F746D702F666F6F20626172' rc, report = cmd([aadecode_bin, test_code]) result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEqual(expected, rc, result + report) result = 'Got output "%s", expected "%s"\n' % (report, expected_output) self.assertIn(expected_output, report, result + report) def test_simple_filter(self): '''test simple decoding of the name argument''' expected_string = 'name="/tmp/foo bar"' content = \ '''type=AVC msg=audit(1348982151.183:2934): apparmor="DENIED" operation="open" parent=30751 profile="/usr/lib/firefox/firefox{,*[^s] [^h]}" name=2F746D702F666F6F20626172 pid=30833 comm="plugin-containe" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0 ''' self._run_file_test(content, [expected_string]) def test_simple_multiline(self): '''test simple multiline decoding of the name argument''' expected_strings = ['ses=4294967295 new ses=2762', 'name="/tmp/foo bar"', 'name="/home/steve/tmp/my test file"'] content = \ ''' type=LOGIN msg=audit(1348980001.155:2925): login pid=17875 uid=0 old auid=4294967295 new auid=0 old ses=4294967295 new ses=2762 type=AVC msg=audit(1348982151.183:2934): apparmor="DENIED" operation="open" parent=30751 profile="/usr/lib/firefox/firefox{,*[^s] [^h]}" name=2F746D702F666F6F20626172 pid=30833 comm="plugin-containe" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0 type=AVC msg=audit(1348982148.195:2933): apparmor="DENIED" operation="file_lock" parent=5490 profile="/usr/lib/firefox/firefox{,*[^s][^h]}" name=2F686F6D652F73746576652F746D702F6D7920746573742066696C65 pid=30737 comm="firefox" requested_mask="k" denied_mask="k" fsuid=1000 ouid=1000 ''' self._run_file_test(content, expected_strings) def test_simple_profile(self): '''test simple decoding of the profile argument''' '''Example take from LP: #897957''' expected_strings = ['name="/lib/x86_64-linux-gnu/libdl-2.13.so"', 'profile="/test space"'] content = \ '''[289763.843292] type=1400 audit(1322614912.304:857): apparmor="ALLOWED" operation="getattr" parent=16001 profile=2F74657374207370616365 name="/lib/x86_64-linux-gnu/libdl-2.13.so" pid=17011 comm="bash" requested_mask="r" denied_mask="r" fsuid=0 ouid=0 ''' self._run_file_test(content, expected_strings) def test_simple_profile2(self): '''test simple decoding of name and profile argument''' '''Example take from LP: #897957''' expected_strings = ['name="/home/steve/tmp/my test file"', 'profile="/home/steve/tmp/my prog.sh"'] content = \ '''type=AVC msg=audit(1349805073.402:6857): apparmor="DENIED" operation="mknod" parent=5890 profile=2F686F6D652F73746576652F746D702F6D792070726F672E7368 name=2F686F6D652F73746576652F746D702F6D7920746573742066696C65 pid=5891 comm="touch" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 ''' self._run_file_test(content, expected_strings) def test_simple_embedded_carat(self): '''test simple decoding of embedded ^ in files''' expected_strings = ['name="/home/steve/tmp/my test ^file"'] content = \ '''type=AVC msg=audit(1349805073.402:6857): apparmor="DENIED" operation="mknod" parent=5890 profile="/usr/bin/test_profile" name=2F686F6D652F73746576652F746D702F6D792074657374205E66696C65 pid=5891 comm="touch" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 ''' self._run_file_test(content, expected_strings) def test_simple_embedded_backslash_carat(self): '''test simple decoding of embedded \^ in files''' expected_strings = ['name="/home/steve/tmp/my test \^file"'] content = \ '''type=AVC msg=audit(1349805073.402:6857): apparmor="DENIED" operation="mknod" parent=5890 profile="/usr/bin/test_profile" name=2F686F6D652F73746576652F746D702F6D792074657374205C5E66696C65 pid=5891 comm="touch" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 ''' self._run_file_test(content, expected_strings) def test_simple_embedded_singlequote(self): '''test simple decoding of embedded \' in files''' expected_strings = ['name="/home/steve/tmp/my test \'file"'] content = \ '''type=AVC msg=audit(1349805073.402:6857): apparmor="DENIED" operation="mknod" parent=5890 profile="/usr/bin/test_profile" name=2F686F6D652F73746576652F746D702F6D792074657374202766696C65 pid=5891 comm="touch" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 ''' self._run_file_test(content, expected_strings) def test_simple_encoded_nonpath_profiles(self): '''test simple decoding of nonpath profiles''' expected_strings = ['name="/lib/x86_64-linux-gnu/libdl-2.13.so"', 'profile="test space"'] content = \ '''[289763.843292] type=1400 audit(1322614912.304:857): apparmor="ALLOWED" operation="getattr" parent=16001 profile=74657374207370616365 name="/lib/x86_64-linux-gnu/libdl-2.13.so" pid=17011 comm="bash" requested_mask="r" denied_mask="r" fsuid=0 ouid=0 ''' self._run_file_test(content, expected_strings) # # Main # if __name__ == '__main__': if 'APPARMOR_DECODE' in os.environ: aadecode_bin = os.environ['APPARMOR_DECODE'] unittest.main(verbosity=1) apparmor-2.13.3/utils/test/cleanprof_test.out0000644000175000017500000000127413502024172017071 0ustar jjjjabi , alias /foo -> /bar, #include # A simple test comment which will persist /usr/bin/a/simple/cleanprof/test/profile { abi "abi/4.20" , #include set rlimit nofile <= 256, audit capability, network stream, dbus send bus=session, signal set=(abrt alrm bus chld fpe hup ill int kill pipe quit segv stkflt term trap usr1 usr2), unix (receive) type=dgram, link subset /alpha/beta -> /tmp/**, allow /home/*/** r, allow /home/foo/** w, change_profile, ^foo { capability dac_override, /etc/fstab r, } } /usr/bin/other/cleanprof/test/profile { allow /home/*/** rw, allow /home/foo/bar r, } apparmor-2.13.3/utils/test/test-aa.py0000644000175000017500000015015113502024172015237 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2014-2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import unittest from common_test import AATest, setup_all_loops, setup_aa from common_test import read_file, write_file import os import shutil import sys import apparmor.aa # needed to set global vars in some tests from apparmor.aa import (check_for_apparmor, get_output, get_reqs, get_interpreter_and_abstraction, create_new_profile, get_profile_flags, change_profile_flags, set_options_audit_mode, set_options_owner_mode, is_skippable_file, is_skippable_dir, parse_profile_start, parse_profile_data, separate_vars, store_list_var, write_header, var_transform, serialize_parse_profile_start, get_file_perms, propose_file_rules) from apparmor.aare import AARE from apparmor.common import AppArmorException, AppArmorBug from apparmor.rule.file import FileRule class AaTestWithTempdir(AATest): def AASetup(self): self.createTmpdir() class AaTest_check_for_apparmor(AaTestWithTempdir): FILESYSTEMS_WITH_SECURITYFS = 'nodev\tdevtmpfs\nnodev\tsecurityfs\nnodev\tsockfs\n\text3\n\text2\n\text4' FILESYSTEMS_WITHOUT_SECURITYFS = 'nodev\tdevtmpfs\nnodev\tsockfs\n\text3\n\text2\n\text4' MOUNTS_WITH_SECURITYFS = ( 'proc /proc proc rw,relatime 0 0\n' 'securityfs %s/security securityfs rw,nosuid,nodev,noexec,relatime 0 0\n' '/dev/sda1 / ext3 rw,noatime,data=ordered 0 0' ) MOUNTS_WITHOUT_SECURITYFS = ( 'proc /proc proc rw,relatime 0 0\n' '/dev/sda1 / ext3 rw,noatime,data=ordered 0 0' ) def test_check_for_apparmor_None_1(self): filesystems = write_file(self.tmpdir, 'filesystems', self.FILESYSTEMS_WITHOUT_SECURITYFS) mounts = write_file(self.tmpdir, 'mounts', self.MOUNTS_WITH_SECURITYFS) self.assertEqual(None, check_for_apparmor(filesystems, mounts)) def test_check_for_apparmor_None_2(self): filesystems = write_file(self.tmpdir, 'filesystems', self.FILESYSTEMS_WITHOUT_SECURITYFS) mounts = write_file(self.tmpdir, 'mounts', self.MOUNTS_WITHOUT_SECURITYFS) self.assertEqual(None, check_for_apparmor(filesystems, mounts)) def test_check_for_apparmor_None_3(self): filesystems = write_file(self.tmpdir, 'filesystems', self.FILESYSTEMS_WITH_SECURITYFS) mounts = write_file(self.tmpdir, 'mounts', self.MOUNTS_WITHOUT_SECURITYFS) self.assertEqual(None, check_for_apparmor(filesystems, mounts)) def test_check_for_apparmor_securityfs_invalid_filesystems(self): filesystems = '' mounts = write_file(self.tmpdir, 'mounts', self.MOUNTS_WITH_SECURITYFS % self.tmpdir) self.assertEqual(None, check_for_apparmor(filesystems, mounts)) def test_check_for_apparmor_securityfs_invalid_mounts(self): filesystems = write_file(self.tmpdir, 'filesystems', self.FILESYSTEMS_WITH_SECURITYFS) mounts = '' self.assertEqual(None, check_for_apparmor(filesystems, mounts)) def test_check_for_apparmor_invalid_securityfs_path(self): filesystems = write_file(self.tmpdir, 'filesystems', self.FILESYSTEMS_WITH_SECURITYFS) mounts = write_file(self.tmpdir, 'mounts', self.MOUNTS_WITH_SECURITYFS % 'xxx') self.assertEqual(None, check_for_apparmor(filesystems, mounts)) def test_check_for_apparmor_securityfs_mounted(self): filesystems = write_file(self.tmpdir, 'filesystems', self.FILESYSTEMS_WITH_SECURITYFS) mounts = write_file(self.tmpdir, 'mounts', self.MOUNTS_WITH_SECURITYFS % self.tmpdir) self.assertEqual('%s/security/apparmor' % self.tmpdir, check_for_apparmor(filesystems, mounts)) class AATest_get_output(AATest): tests = [ (['./fake_ldd', '/AATest/lib64/libc-2.22.so'], (0, [' /AATest/lib64/ld-linux-x86-64.so.2 (0x0000556858473000)', ' linux-vdso.so.1 (0x00007ffe98912000)'] )), (['./fake_ldd', '/tmp/aa-test-foo'], (0, [' not a dynamic executable'] )), (['./fake_ldd', 'invalid'], (1, [] )), # stderr is not part of output ] def _run_test(self, params, expected): self.assertEqual(get_output(params), expected) def test_get_output_nonexisting(self): with self.assertRaises(AppArmorException): ret, output = get_output(['./_file_/_not_/_found_']) class AATest_get_reqs(AATest): tests = [ ('/AATest/bin/bash', ['/AATest/lib64/libreadline.so.6', '/AATest/lib64/libtinfo.so.6', '/AATest/lib64/libdl.so.2', '/AATest/lib64/libc.so.6', '/AATest/lib64/ld-linux-x86-64.so.2']), ('/tmp/aa-test-foo', []), ('/AATest/sbin/ldconfig', []), # comes with $? == 1 ] def _run_test(self, params, expected): # for some reason, setting the ldd config option does not get # honored in python2.7 # XXX KILL when python 2.7 is dropped XXX if sys.version_info[0] < 3: print("Skipping on python < 3.x") return apparmor.aa.cfg['settings']['ldd'] = './fake_ldd' self.assertEqual(get_reqs(params), expected) class AaTest_create_new_profile(AATest): tests = [ # file content expected interpreter expected abstraction (besides 'base') ('#!/bin/bash\ntrue', (u'/bin/bash', 'abstractions/bash')), ('foo bar', (None, None)), ] def _run_test(self, params, expected): apparmor.aa.cfg['settings']['ldd'] = './fake_ldd' # for some reason, setting the ldd config option does not get # honored in python2.7 # XXX KILL when python 2.7 is dropped XXX if sys.version_info[0] < 3: print("Skipping on python < 3.x") return self.createTmpdir() #copy the local profiles to the test directory self.profile_dir = '%s/profiles' % self.tmpdir shutil.copytree('../../profiles/apparmor.d/', self.profile_dir, symlinks=True) # load the abstractions we need in the test apparmor.aa.profiledir = self.profile_dir apparmor.aa.load_include('abstractions/base') apparmor.aa.load_include('abstractions/bash') exp_interpreter_path, exp_abstraction = expected # damn symlinks! if exp_interpreter_path: exp_interpreter_path = os.path.realpath(exp_interpreter_path) program = self.writeTmpfile('script', params) profile = create_new_profile(program) if exp_interpreter_path: self.assertEqual(set(profile[program][program]['file'].get_clean()), {'%s ix,' % exp_interpreter_path, '%s r,' % program, '', '/AATest/lib64/libtinfo.so.* mr,', '/AATest/lib64/libc.so.* mr,', '/AATest/lib64/libdl.so.* mr,', '/AATest/lib64/libreadline.so.* mr,', '/AATest/lib64/ld-linux-x86-64.so.* mr,' }) else: self.assertEqual(set(profile[program][program]['file'].get_clean()), {'%s mr,' % program, ''}) if exp_abstraction: self.assertEqual(set(profile[program][program]['include'].keys()), {exp_abstraction, 'abstractions/base'}) else: self.assertEqual(set(profile[program][program]['include'].keys()), {'abstractions/base'}) class AaTest_get_interpreter_and_abstraction(AATest): tests = [ ('#!/bin/bash', ('/bin/bash', 'abstractions/bash')), ('#!/bin/dash', ('/bin/dash', 'abstractions/bash')), ('#!/bin/sh', ('/bin/sh', 'abstractions/bash')), ('#! /bin/sh ', ('/bin/sh', 'abstractions/bash')), ('#! /bin/sh -x ', ('/bin/sh', 'abstractions/bash')), # '-x' is not part of the interpreter path ('#!/usr/bin/perl', ('/usr/bin/perl', 'abstractions/perl')), ('#!/usr/bin/perl -w', ('/usr/bin/perl', 'abstractions/perl')), # '-w' is not part of the interpreter path ('#!/usr/bin/python', ('/usr/bin/python', 'abstractions/python')), ('#!/usr/bin/python2', ('/usr/bin/python2', 'abstractions/python')), ('#!/usr/bin/python2.7', ('/usr/bin/python2.7', 'abstractions/python')), ('#!/usr/bin/python3', ('/usr/bin/python3', 'abstractions/python')), ('#!/usr/bin/python4', ('/usr/bin/python4', None)), # python abstraction is only applied to py2 and py3 ('#!/usr/bin/ruby', ('/usr/bin/ruby', 'abstractions/ruby')), ('#!/usr/bin/ruby2.2', ('/usr/bin/ruby2.2', 'abstractions/ruby')), ('#!/usr/bin/ruby1.9.1', ('/usr/bin/ruby1.9.1', 'abstractions/ruby')), ('#!/usr/bin/foobarbaz', ('/usr/bin/foobarbaz', None)), # we don't have an abstraction for "foobarbaz" ('foo', (None, None)), # no hashbang - not a script ] def _run_test(self, params, expected): exp_interpreter_path, exp_abstraction = expected program = self.writeTmpfile('program', "%s\nfoo\nbar" % params) interpreter_path, abstraction = get_interpreter_and_abstraction(program) # damn symlinks! if exp_interpreter_path: exp_interpreter_path = os.path.realpath(exp_interpreter_path) self.assertEqual(interpreter_path, exp_interpreter_path) self.assertEqual(abstraction, exp_abstraction) def test_special_file(self): self.assertEqual((None, None), get_interpreter_and_abstraction('/dev/null')) def test_file_not_found(self): self.createTmpdir() self.assertEqual((None, None), get_interpreter_and_abstraction('%s/file-not-found' % self.tmpdir)) class AaTest_get_profile_flags(AaTestWithTempdir): def _test_get_flags(self, profile_header, expected_flags): file = write_file(self.tmpdir, 'profile', '%s {\n}\n' % profile_header) flags = get_profile_flags(file, '/foo') self.assertEqual(flags, expected_flags) def test_get_flags_01(self): self._test_get_flags('/foo', None) def test_get_flags_02(self): self._test_get_flags('/foo ( complain )', ' complain ') def test_get_flags_04(self): self._test_get_flags('/foo (complain)', 'complain') def test_get_flags_05(self): self._test_get_flags('/foo flags=(complain)', 'complain') def test_get_flags_06(self): self._test_get_flags('/foo flags=(complain, audit)', 'complain, audit') def test_get_flags_invalid_01(self): with self.assertRaises(AppArmorException): self._test_get_flags('/foo ()', None) def test_get_flags_invalid_02(self): with self.assertRaises(AppArmorException): self._test_get_flags('/foo flags=()', None) def test_get_flags_invalid_03(self): with self.assertRaises(AppArmorException): self._test_get_flags('/foo ( )', ' ') def test_get_flags_other_profile(self): with self.assertRaises(AppArmorException): self._test_get_flags('/no-such-profile flags=(complain)', 'complain') class AaTest_change_profile_flags(AaTestWithTempdir): def _test_change_profile_flags(self, profile, old_flags, flags_to_change, set_flag, expected_flags, whitespace='', comment='', more_rules='', expected_more_rules='@-@-@', check_new_flags=True, profile_name='/foo'): if old_flags: old_flags = ' %s' % old_flags if expected_flags: expected_flags = ' flags=(%s)' % (expected_flags) else: expected_flags = '' if expected_more_rules == '@-@-@': expected_more_rules = more_rules if comment: comment = ' %s' % comment dummy_profile_content = ' #include \n capability chown,\n /bar r,' prof_template = '%s%s%s {%s\n%s\n%s\n}\n' old_prof = prof_template % (whitespace, profile, old_flags, comment, more_rules, dummy_profile_content) new_prof = prof_template % (whitespace, profile, expected_flags, comment, expected_more_rules, dummy_profile_content) self.file = write_file(self.tmpdir, 'profile', old_prof) change_profile_flags(self.file, profile_name, flags_to_change, set_flag) if check_new_flags: real_new_prof = read_file(self.file) self.assertEqual(new_prof, real_new_prof) # tests that actually don't change the flags def test_change_profile_flags_nochange_02(self): self._test_change_profile_flags('/foo', '( complain )', 'complain', True, 'complain', whitespace=' ') def test_change_profile_flags_nochange_03(self): self._test_change_profile_flags('/foo', '(complain)', 'complain', True, 'complain') def test_change_profile_flags_nochange_04(self): self._test_change_profile_flags('/foo', 'flags=(complain)', 'complain', True, 'complain') def test_change_profile_flags_nochange_05(self): self._test_change_profile_flags('/foo', 'flags=(complain, audit)', 'complain', True, 'audit, complain', whitespace=' ') def test_change_profile_flags_nochange_06(self): self._test_change_profile_flags('/foo', 'flags=(complain, audit)', 'complain', True, 'audit, complain', whitespace=' ', comment='# a comment') def test_change_profile_flags_nochange_07(self): self._test_change_profile_flags('/foo', 'flags=(complain, audit)', 'audit', True, 'audit, complain', whitespace=' ', more_rules=' # a comment\n#another comment') def test_change_profile_flags_nochange_08(self): self._test_change_profile_flags('profile /foo', 'flags=(complain)', 'complain', True, 'complain') def test_change_profile_flags_nochange_09(self): self._test_change_profile_flags('profile xy /foo', 'flags=(complain)', 'complain', True, 'complain', profile_name='xy') def test_change_profile_flags_nochange_10(self): self._test_change_profile_flags('profile "/foo bar"', 'flags=(complain)', 'complain', True, 'complain', profile_name='/foo bar') def test_change_profile_flags_nochange_11(self): self._test_change_profile_flags('/foo', '(complain)', 'complain', True, 'complain', profile_name=None) def test_change_profile_flags_nochange_12(self): # XXX changes the flags for the child profile (which happens to have the same profile name) to 'complain' self._test_change_profile_flags('/foo', 'flags=(complain)', 'complain', True, 'complain', more_rules=' profile /foo {\n}', expected_more_rules=' profile /foo flags=(complain) {\n}') # tests that change the flags def test_change_profile_flags_01(self): self._test_change_profile_flags('/foo', '', 'audit', True, 'audit') def test_change_profile_flags_02(self): self._test_change_profile_flags('/foo', '( complain )', 'audit', True, 'audit, complain', whitespace=' ') def test_change_profile_flags_04(self): self._test_change_profile_flags('/foo', '(complain)', 'audit', True, 'audit, complain') def test_change_profile_flags_05(self): self._test_change_profile_flags('/foo', 'flags=(complain)', 'audit', True, 'audit, complain') def test_change_profile_flags_06(self): self._test_change_profile_flags('/foo', 'flags=(complain, audit)', 'complain', False, 'audit', whitespace=' ') def test_change_profile_flags_07(self): self._test_change_profile_flags('/foo', 'flags=(complain, audit)', 'audit', False, 'complain') def test_change_profile_flags_08(self): self._test_change_profile_flags('/foo', '( complain )', 'audit', True, 'audit, complain', whitespace=' ', profile_name=None) def test_change_profile_flags_09(self): self._test_change_profile_flags('profile /foo', 'flags=(complain)', 'audit', True, 'audit, complain') def test_change_profile_flags_10(self): self._test_change_profile_flags('profile xy /foo', 'flags=(complain)', 'audit', True, 'audit, complain', profile_name='xy') def test_change_profile_flags_11(self): self._test_change_profile_flags('profile "/foo bar"', 'flags=(complain)', 'audit', True, 'audit, complain', profile_name='/foo bar') def test_change_profile_flags_12(self): self._test_change_profile_flags('profile xy "/foo bar"', 'flags=(complain)', 'audit', True, 'audit, complain', profile_name='xy') def test_change_profile_flags_13(self): self._test_change_profile_flags('/foo', '(audit)', 'audit', False, '') # test handling of hat flags def test_set_flags_with_hat_01(self): self._test_change_profile_flags('/foo', 'flags=(complain)', 'audit', True, 'audit, complain', more_rules='\n ^foobar {\n}\n', expected_more_rules='\n ^foobar flags=(audit) {\n}\n' ) def test_change_profile_flags_with_hat_02(self): self._test_change_profile_flags('/foo', 'flags=(complain)', 'audit', False, 'complain', profile_name=None, more_rules='\n ^foobar flags=(audit) {\n}\n', expected_more_rules='\n ^foobar {\n}\n' ) def test_change_profile_flags_with_hat_03(self): self._test_change_profile_flags('/foo', 'flags=(complain)', 'audit', True, 'audit, complain', more_rules='\n^foobar (attach_disconnected) { # comment\n}\n', expected_more_rules='\n^foobar flags=(attach_disconnected, audit) { # comment\n}\n' ) def test_change_profile_flags_with_hat_04(self): self._test_change_profile_flags('/foo', '', 'audit', True, 'audit', more_rules='\n hat foobar (attach_disconnected) { # comment\n}\n', expected_more_rules='\n hat foobar flags=(attach_disconnected, audit) { # comment\n}\n' ) def test_change_profile_flags_with_hat_05(self): self._test_change_profile_flags('/foo', '(audit)', 'audit', False, '', more_rules='\n hat foobar (attach_disconnected) { # comment\n}\n', expected_more_rules='\n hat foobar flags=(attach_disconnected) { # comment\n}\n' ) # test handling of child profiles def test_change_profile_flags_with_child_01(self): self._test_change_profile_flags('/foo', 'flags=(complain)', 'audit', True, 'audit, complain', profile_name=None, more_rules='\n profile /bin/bar {\n}\n', expected_more_rules='\n profile /bin/bar flags=(audit) {\n}\n' ) def test_change_profile_flags_with_child_02(self): # XXX child profile flags aren't changed if profile parameter is not None self._test_change_profile_flags('/foo', 'flags=(complain)', 'audit', True, 'audit, complain', more_rules='\n profile /bin/bar {\n}\n', expected_more_rules='\n profile /bin/bar {\n}\n' # flags(audit) should be added ) def test_change_profile_flags_invalid_01(self): with self.assertRaises(AppArmorBug): self._test_change_profile_flags('/foo', '()', None, False, '', check_new_flags=False) def test_change_profile_flags_invalid_02(self): with self.assertRaises(AppArmorBug): self._test_change_profile_flags('/foo', 'flags=()', None, True, '', check_new_flags=False) def test_change_profile_flags_invalid_03(self): with self.assertRaises(AppArmorBug): self._test_change_profile_flags('/foo', '( )', '', True, '', check_new_flags=False) def test_change_profile_flags_invalid_04(self): with self.assertRaises(AppArmorBug): self._test_change_profile_flags('/foo', 'flags=(complain, audit)', ' ', True, 'audit, complain', check_new_flags=False) # whitespace-only newflags def test_change_profile_flags_other_profile(self): # test behaviour if the file doesn't contain the specified /foo profile orig_prof = '/no-such-profile flags=(complain) {\n}' self.file = write_file(self.tmpdir, 'profile', orig_prof) with self.assertRaises(AppArmorException): change_profile_flags(self.file, '/foo', 'audit', True) # the file should not be changed real_new_prof = read_file(self.file) self.assertEqual(orig_prof, real_new_prof) def test_change_profile_flags_no_profile_found(self): # test behaviour if the file doesn't contain any profile orig_prof = '# /comment flags=(complain) {\n# }' self.file = write_file(self.tmpdir, 'profile', orig_prof) with self.assertRaises(AppArmorException): change_profile_flags(self.file, None, 'audit', True) # the file should not be changed real_new_prof = read_file(self.file) self.assertEqual(orig_prof, real_new_prof) def test_change_profile_flags_file_not_found(self): with self.assertRaises(IOError): change_profile_flags('%s/file-not-found' % self.tmpdir, '/foo', 'audit', True) class AaTest_set_options_audit_mode(AATest): tests = [ ((FileRule.parse('audit /foo/bar r,'), ['/foo/bar r,', '/foo/* r,', '/** r,'] ), ['audit /foo/bar r,', 'audit /foo/* r,', 'audit /** r,']), ((FileRule.parse('audit /foo/bar r,'), ['/foo/bar r,', 'audit /foo/* r,', 'audit /** r,'] ), ['audit /foo/bar r,', 'audit /foo/* r,', 'audit /** r,']), ((FileRule.parse('/foo/bar r,'), ['/foo/bar r,', '/foo/* r,', '/** r,'] ), ['/foo/bar r,', '/foo/* r,', '/** r,']), ((FileRule.parse('/foo/bar r,'), ['audit /foo/bar r,', 'audit /foo/* r,', 'audit /** r,'] ), ['/foo/bar r,', '/foo/* r,', '/** r,']), ((FileRule.parse('audit /foo/bar r,'), ['/foo/bar r,', '/foo/* r,', '#include ']), ['audit /foo/bar r,', 'audit /foo/* r,', '#include ']), ] def _run_test(self, params, expected): rule_obj, options = params new_options = set_options_audit_mode(rule_obj, options) self.assertEqual(new_options, expected) class AaTest_set_options_owner_mode(AATest): tests = [ ((FileRule.parse('owner /foo/bar r,'), ['/foo/bar r,', '/foo/* r,', '/** r,'] ), ['owner /foo/bar r,', 'owner /foo/* r,', 'owner /** r,']), ((FileRule.parse('owner /foo/bar r,'), ['/foo/bar r,', 'owner /foo/* r,', 'owner /** r,'] ), ['owner /foo/bar r,', 'owner /foo/* r,', 'owner /** r,']), ((FileRule.parse('/foo/bar r,'), ['/foo/bar r,', '/foo/* r,', '/** r,'] ), ['/foo/bar r,', '/foo/* r,', '/** r,']), ((FileRule.parse('/foo/bar r,'), ['owner /foo/bar r,', 'owner /foo/* r,', 'owner /** r,'] ), ['/foo/bar r,', '/foo/* r,', '/** r,']), ((FileRule.parse('audit owner /foo/bar r,'),['audit /foo/bar r,', 'audit /foo/* r,', '#include ']), ['audit owner /foo/bar r,', 'audit owner /foo/* r,', '#include ']), ] def _run_test(self, params, expected): rule_obj, options = params new_options = set_options_owner_mode(rule_obj, options) self.assertEqual(new_options, expected) class AaTest_is_skippable_file(AATest): def test_not_skippable_01(self): self.assertFalse(is_skippable_file('bin.ping')) def test_not_skippable_02(self): self.assertFalse(is_skippable_file('usr.lib.dovecot.anvil')) def test_not_skippable_03(self): self.assertFalse(is_skippable_file('bin.~ping')) def test_not_skippable_04(self): self.assertFalse(is_skippable_file('bin.rpmsave.ping')) def test_not_skippable_05(self): # normally is_skippable_file should be called without directory, but it shouldn't hurt too much self.assertFalse(is_skippable_file('/etc/apparmor.d/bin.ping')) def test_not_skippable_06(self): self.assertFalse(is_skippable_file('bin.pingrej')) def test_skippable_01(self): self.assertTrue(is_skippable_file('bin.ping.dpkg-new')) def test_skippable_02(self): self.assertTrue(is_skippable_file('bin.ping.dpkg-old')) def test_skippable_03(self): self.assertTrue(is_skippable_file('bin.ping..dpkg-dist')) def test_skippable_04(self): self.assertTrue(is_skippable_file('bin.ping..dpkg-bak')) def test_skippable_05(self): self.assertTrue(is_skippable_file('bin.ping.dpkg-remove')) def test_skippable_06(self): self.assertTrue(is_skippable_file('bin.ping.pacsave')) def test_skippable_07(self): self.assertTrue(is_skippable_file('bin.ping.pacnew')) def test_skippable_08(self): self.assertTrue(is_skippable_file('bin.ping.rpmnew')) def test_skippable_09(self): self.assertTrue(is_skippable_file('bin.ping.rpmsave')) def test_skippable_10(self): self.assertTrue(is_skippable_file('bin.ping.orig')) def test_skippable_11(self): self.assertTrue(is_skippable_file('bin.ping.rej')) def test_skippable_12(self): self.assertTrue(is_skippable_file('bin.ping~')) def test_skippable_13(self): self.assertTrue(is_skippable_file('.bin.ping')) def test_skippable_14(self): self.assertTrue(is_skippable_file('')) # empty filename def test_skippable_15(self): self.assertTrue(is_skippable_file('/etc/apparmor.d/')) # directory without filename def test_skippable_16(self): self.assertTrue(is_skippable_file('README')) class AaTest_is_skippable_dir(AATest): tests = [ ('disable', True), ('cache', True), ('lxc', True), ('force-complain', True), ('/etc/apparmor.d/cache', True), ('/etc/apparmor.d/cache.d', True), ('/etc/apparmor.d/cache.d/', True), ('/etc/apparmor.d/lxc/', True), ('/etc/apparmor.d/.git/', True), ('dont_disable', False), ('/etc/apparmor.d/cache_foo', False), ('abstractions', False), ('apache2.d', False), ('/etc/apparmor.d/apache2.d', False), ('local', False), ('/etc/apparmor.d/local/', False), ('tunables', False), ('/etc/apparmor.d/tunables', False), ('/etc/apparmor.d/tunables/multiarch.d', False), ('/etc/apparmor.d/tunables/xdg-user-dirs.d', False), ('/etc/apparmor.d/tunables/home.d', False), ('/etc/apparmor.d/abstractions', False), ('/etc/apparmor.d/abstractions/ubuntu-browsers.d', False), ('/etc/apparmor.d/abstractions/apparmor_api', False), ] def _run_test(self, params, expected): self.assertEqual(is_skippable_dir(params), expected) class AaTest_parse_profile_start(AATest): def _parse(self, line, profile, hat): return parse_profile_start(line, 'somefile', 1, profile, hat) # (profile, hat, flags, in_contained_hat, pps_set_profile, pps_set_hat_external) def test_parse_profile_start_01(self): result = self._parse('/foo {', None, None) expected = ('/foo', '/foo', None, None, False, False, False) self.assertEqual(result, expected) def test_parse_profile_start_02(self): result = self._parse('/foo (complain) {', None, None) expected = ('/foo', '/foo', None, 'complain', False, False, False) self.assertEqual(result, expected) def test_parse_profile_start_03(self): result = self._parse('profile foo /foo {', None, None) # named profile expected = ('foo', 'foo', '/foo', None, False, False, False) self.assertEqual(result, expected) def test_parse_profile_start_04(self): result = self._parse('profile /foo {', '/bar', '/bar') # child profile expected = ('/bar', '/foo', None, None, True, True, False) self.assertEqual(result, expected) def test_parse_profile_start_05(self): result = self._parse('/foo//bar {', None, None) # external hat expected = ('/foo', 'bar', None, None, False, False, True) self.assertEqual(result, expected) def test_parse_profile_start_06(self): result = self._parse('profile "/foo" (complain) {', None, None) expected = ('/foo', '/foo', None, 'complain', False, False, False) self.assertEqual(result, expected) def test_parse_profile_start_unsupported_01(self): with self.assertRaises(AppArmorException): self._parse('/foo///bar///baz {', None, None) # XXX deeply nested external hat def test_parse_profile_start_invalid_01(self): with self.assertRaises(AppArmorException): self._parse('/foo {', '/bar', '/bar') # child profile without profile keyword def test_parse_profile_start_invalid_02(self): with self.assertRaises(AppArmorBug): self._parse('xy', '/bar', '/bar') # not a profile start class AaTest_parse_profile_data(AATest): def test_parse_empty_profile_01(self): prof = parse_profile_data('/foo {\n}\n'.split(), 'somefile', False) self.assertEqual(list(prof.keys()), ['/foo']) self.assertEqual(list(prof['/foo'].keys()), ['/foo']) self.assertEqual(prof['/foo']['/foo']['name'], '/foo') self.assertEqual(prof['/foo']['/foo']['filename'], 'somefile') self.assertEqual(prof['/foo']['/foo']['flags'], None) def test_parse_empty_profile_02(self): with self.assertRaises(AppArmorException): # file contains two profiles with the same name parse_profile_data('profile /foo {\n}\nprofile /foo {\n}\n'.split(), 'somefile', False) class AaTest_separate_vars(AATest): tests = [ ('' , set() ), (' ' , set() ), (' foo bar' , {'foo', 'bar' }), ('foo " ' , AppArmorException ), (' " foo ' , AppArmorException ), # half-quoted (' foo bar ' , {'foo', 'bar' }), (' foo bar # comment' , {'foo', 'bar', '#', 'comment'}), # XXX should comments be stripped? ('foo' , {'foo' }), ('"foo" "bar baz"' , {'foo', 'bar baz' }), ('foo "bar baz" xy' , {'foo', 'bar baz', 'xy' }), ('foo "bar baz ' , AppArmorException ), # half-quoted (' " foo" bar' , {' foo', 'bar' }), (' " foo" bar x' , {' foo', 'bar', 'x' }), ('""' , {'' }), # empty value ('"" foo' , {'', 'foo' }), # empty value + 'foo' ('"" foo "bar"' , {'', 'foo', 'bar' }), # empty value + 'foo' + 'bar' (bar has superfluous quotes) ('"bar"' , {'bar' }), # 'bar' with superfluous quotes ] def _run_test(self, params, expected): if expected == AppArmorException: with self.assertRaises(expected): separate_vars(params) else: result = separate_vars(params) self.assertEqual(result, expected) class AaTest_store_list_var(AATest): tests = [ # old var value operation expected (False for exception) ([ {} , 'foo' , '=' ], {'foo'} ), # set ([ {} , 'foo bar' , '=' ], {'foo', 'bar'} ), # set multi ([ {'@{var}': {'foo'}} , 'bar' , '=' ], False ), # redefine var ([ {} , 'bar' , '+=' ], False ), # add to undefined var ([ {'@{var}': {'foo'}} , 'bar' , '+=' ], {'foo', 'bar'} ), # add ([ {'@{var}': {'foo'}} , 'bar baz' , '+=' ], {'foo', 'bar', 'baz'} ), # add multi ([ {'@{var}': {'foo', 'xy'}} , 'bar baz' , '+=' ], {'foo', 'xy', 'bar', 'baz'} ), # add multi to multi ([ {} , 'foo' , '-=' ], False ), # unknown operation ] def _run_test(self, params, expected): var = params[0] value = params[1] operation = params[2] if not expected: with self.assertRaises(AppArmorException): store_list_var(var, '@{var}', value, operation, 'somefile') return # dumy value that must not be changed var['@{foo}'] = {'one', 'two'} exp_var = { '@{foo}': {'one', 'two'}, '@{var}': expected, } store_list_var(var, '@{var}', value, operation, 'somefile') self.assertEqual(var.keys(), exp_var.keys()) for key in exp_var: self.assertEqual(var[key], exp_var[key]) class AaTest_write_header(AATest): tests = [ # name embedded_hat write_flags depth flags attachment prof.keyw. comment expected (['/foo', False, True, 1, 'complain', None, None, None ], ' /foo flags=(complain) {'), (['/foo', True, True, 1, 'complain', None, None, None ], ' profile /foo flags=(complain) {'), (['/foo sp', False, False, 2, 'complain', None, None, None ], ' "/foo sp" {'), (['/foo' ,False, False, 2, 'complain', None, None, None ], ' /foo {'), (['/foo', True, False, 2, 'complain', None, None, None ], ' profile /foo {'), (['/foo', False, True, 0, None, None, None, None ], '/foo {'), (['/foo', True, True, 0, None, None, None, None ], 'profile /foo {'), (['/foo', False, False, 0, None, None, None, None ], '/foo {'), (['/foo', True, False, 0, None, None, None, None ], 'profile /foo {'), (['bar', False, True, 1, 'complain', None, None, None ], ' profile bar flags=(complain) {'), (['bar', False, True, 1, 'complain', '/foo', None, None ], ' profile bar /foo flags=(complain) {'), (['bar', True, True, 1, 'complain', '/foo', None, None ], ' profile bar /foo flags=(complain) {'), (['bar baz', False, True, 1, None, '/foo', None, None ], ' profile "bar baz" /foo {'), (['bar', True, True, 1, None, '/foo', None, None ], ' profile bar /foo {'), (['bar baz', False, True, 1, 'complain', '/foo sp', None, None ], ' profile "bar baz" "/foo sp" flags=(complain) {'), (['^foo', False, True, 1, 'complain', None, None, None ], ' profile ^foo flags=(complain) {'), (['^foo', True, True, 1, 'complain', None, None, None ], ' ^foo flags=(complain) {'), (['^foo', True, True, 1.5, 'complain', None, None, None ], ' ^foo flags=(complain) {'), (['^foo', True, True, 1.3, 'complain', None, None, None ], ' ^foo flags=(complain) {'), (['/foo', False, True, 1, 'complain', None, 'profile', None ], ' profile /foo flags=(complain) {'), (['/foo', True, True, 1, 'complain', None, 'profile', None ], ' profile /foo flags=(complain) {'), (['/foo', False, True, 1, 'complain', None, None, '# x' ], ' /foo flags=(complain) { # x'), (['/foo', True, True, 1, None, None, None, '# x' ], ' profile /foo { # x'), (['/foo', False, True, 1, None, None, 'profile', '# x' ], ' profile /foo { # x'), (['/foo', True, True, 1, 'complain', None, 'profile', '# x' ], ' profile /foo flags=(complain) { # x'), ] def _run_test(self, params, expected): name = params[0] embedded_hat = params[1] write_flags = params[2] depth = params[3] prof_data = { 'flags': params[4], 'attachment': params[5], 'profile_keyword': params[6], 'header_comment': params[7] } result = write_header(prof_data, depth, name, embedded_hat, write_flags) self.assertEqual(result, [expected]) class AaTest_var_transform(AATest): tests = [ (['foo', ''], 'foo ""' ), (['foo', 'bar'], 'foo bar' ), ([''], '""' ), (['bar baz', 'foo'], '"bar baz" foo' ), ] def _run_test(self, params, expected): self.assertEqual(var_transform(params), expected) class AaTest_serialize_parse_profile_start(AATest): def _parse(self, line, profile, hat, prof_data_profile, prof_data_external): # 'correct' is always True in the code that uses serialize_parse_profile_start() (set some lines above the function call) return serialize_parse_profile_start(line, 'somefile', 1, profile, hat, prof_data_profile, prof_data_external, True) def test_serialize_parse_profile_start_01(self): result = self._parse('/foo {', None, None, False, False) expected = ('/foo', '/foo', None, None, False, True) self.assertEqual(result, expected) def test_serialize_parse_profile_start_02(self): result = self._parse('/foo (complain) {', None, None, False, False) expected = ('/foo', '/foo', None, 'complain', False, True) self.assertEqual(result, expected) def test_serialize_parse_profile_start_03(self): result = self._parse('profile foo /foo {', None, None, False, False) # named profile expected = ('foo', 'foo', '/foo', None, False, True) self.assertEqual(result, expected) def test_serialize_parse_profile_start_04(self): result = self._parse('profile /foo {', '/bar', '/bar', False, False) # child profile expected = ('/bar', '/foo', None, None, True, True) self.assertEqual(result, expected) def test_serialize_parse_profile_start_05(self): result = self._parse('/foo//bar {', None, None, False, False) # external hat expected = ('/foo', 'bar', None, None, False, False) # note correct == False here self.assertEqual(result, expected) def test_serialize_parse_profile_start_06(self): result = self._parse('profile "/foo" (complain) {', None, None, False, False) expected = ('/foo', '/foo', None, 'complain', False, True) self.assertEqual(result, expected) def test_serialize_parse_profile_start_07(self): result = self._parse('/foo {', None, None, True, False) expected = ('/foo', '/foo', None, None, False, True) self.assertEqual(result, expected) def test_serialize_parse_profile_start_08(self): result = self._parse('/foo {', None, None, False, True) expected = ('/foo', '/foo', None, None, False, True) self.assertEqual(result, expected) def test_serialize_parse_profile_start_09(self): result = self._parse('/foo {', None, None, True, True) expected = ('/foo', '/foo', None, None, False, True) self.assertEqual(result, expected) def test_serialize_parse_profile_start_10(self): result = self._parse('profile /foo {', '/bar', '/bar', True, False) # child profile expected = ('/bar', '/foo', None, None, True, True) self.assertEqual(result, expected) def test_serialize_parse_profile_start_11(self): result = self._parse('profile /foo {', '/bar', '/bar', False, True) # child profile expected = ('/bar', '/foo', None, None, True, True) self.assertEqual(result, expected) def test_serialize_parse_profile_start_12(self): result = self._parse('profile /foo {', '/bar', '/bar', True, True) # child profile expected = ('/bar', '/foo', None, None, True, True) self.assertEqual(result, expected) class AaTestInvalid_serialize_parse_profile_start(AATest): tests = [ # line profile hat p_d_profile p_d_external expected (['/foo {', '/bar', '/bar', False, False ], AppArmorException), # child profile without 'profile' keyword (['profile /foo {', '/bar', '/xy', False, False ], AppArmorException), # already inside a child profile - nesting level reached (['/ext//hat {', '/bar', '/bar', True, True ], AppArmorException), # external hat inside a profile (['/ext//hat {', '/bar', '/bar', True, False ], AppArmorException), # external hat inside a profile (['xy', '/bar', '/bar', False, False ], AppArmorBug ), # not a profile start ] def _run_test(self, params, expected): line = params[0] profile = params[1] hat = params[2] prof_data_profile = params[3] prof_data_external = params[4] with self.assertRaises(expected): # 'correct' is always True in the code that uses serialize_parse_profile_start() (set some lines above the function call) serialize_parse_profile_start(line, 'somefile', 1, profile, hat, prof_data_profile, prof_data_external, True) class AaTest_get_file_perms_1(AATest): tests = [ ('/usr/share/common-licenses/foo/bar', {'allow': {'all': set(), 'owner': {'w'} }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/share/common-licenses/**'} }), ('/dev/null', {'allow': {'all': {'r', 'w', 'k'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/dev/null'} }), ('/foo/bar', {'allow': {'all': {'r', 'w'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/foo/bar'} }), # exec perms not included ('/no/thing', {'allow': {'all': set(), 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': set() }), ('/usr/lib/ispell/', {'allow': {'all': set(), 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': set() }), ('/usr/lib/aspell/*.so', {'allow': {'all': set(), 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': set() }), ] def _run_test(self, params, expected): self.createTmpdir() #copy the local profiles to the test directory self.profile_dir = '%s/profiles' % self.tmpdir shutil.copytree('../../profiles/apparmor.d/', self.profile_dir, symlinks=True) profile = apparmor.aa.ProfileStorage('/test', '/test', 'test-aa.py') # simple profile without any includes profile['file'].add(FileRule.parse('owner /usr/share/common-licenses/** w,')) profile['file'].add(FileRule.parse('/dev/null rwk,')) profile['file'].add(FileRule.parse('/foo/bar rwix,')) perms = get_file_perms(profile, params, False, False) # only testing with audit and deny = False self.assertEqual(perms, expected) class AaTest_get_file_perms_2(AATest): tests = [ ('/usr/share/common-licenses/foo/bar', {'allow': {'all': {'r'}, 'owner': {'w'} }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/share/common-licenses/**'} }), ('/usr/share/common-licenses/what/ever', {'allow': {'all': {'r'}, 'owner': {'w'} }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/share/common-licenses/**', '/usr/share/common-licenses/what/ever'} }), ('/dev/null', {'allow': {'all': {'r', 'w', 'k'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/dev/null'} }), ('/foo/bar', {'allow': {'all': {'r', 'w'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/foo/bar'} }), # exec perms not included ('/no/thing', {'allow': {'all': set(), 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': set() }), ('/usr/lib/ispell/', {'allow': {'all': {'r'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/lib/ispell/', '/{usr/,}lib{,32,64}/**'} }), # from abstractions/enchant ('/usr/lib/aspell/*.so', {'allow': {'all': {'m', 'r'}, 'owner': set() }, 'deny': {'all':set(), 'owner': set()}, 'paths': {'/usr/lib/aspell/*', '/usr/lib/aspell/*.so', '/{usr/,}lib{,32,64}/**', '/{usr/,}lib{,32,64}/**.so*'} }), # from abstractions/aspell via abstractions/enchant and from abstractions/base ] def _run_test(self, params, expected): self.createTmpdir() #copy the local profiles to the test directory self.profile_dir = '%s/profiles' % self.tmpdir shutil.copytree('../../profiles/apparmor.d/', self.profile_dir, symlinks=True) # load the abstractions we need in the test apparmor.aa.profiledir = self.profile_dir apparmor.aa.load_include('abstractions/base') apparmor.aa.load_include('abstractions/bash') apparmor.aa.load_include('abstractions/enchant') apparmor.aa.load_include('abstractions/aspell') profile = apparmor.aa.ProfileStorage('/test', '/test', 'test-aa.py') profile['include']['abstractions/base'] = True profile['include']['abstractions/bash'] = True profile['include']['abstractions/enchant'] = True # includes abstractions/aspell profile['file'].add(FileRule.parse('owner /usr/share/common-licenses/** w,')) profile['file'].add(FileRule.parse('owner /usr/share/common-licenses/what/ever a,')) # covered by the above 'w' rule, so 'a' should be ignored profile['file'].add(FileRule.parse('/dev/null rwk,')) profile['file'].add(FileRule.parse('/foo/bar rwix,')) perms = get_file_perms(profile, params, False, False) # only testing with audit and deny = False self.assertEqual(perms, expected) class AaTest_propose_file_rules(AATest): tests = [ # log event path and perms expected proposals (['/usr/share/common-licenses/foo/bar', 'w'], ['/usr/share/common*/foo/* rw,', '/usr/share/common-licenses/** rw,', '/usr/share/common-licenses/foo/bar rw,'] ), (['/dev/null', 'wk'], ['/dev/null rwk,'] ), (['/foo/bar', 'rw'], ['/foo/bar rw,'] ), (['/usr/lib/ispell/', 'w'], ['/{usr/,}lib{,32,64}/** rw,', '/usr/lib/ispell/ rw,'] ), (['/usr/lib/aspell/some.so', 'k'], ['/usr/lib/aspell/* mrk,', '/usr/lib/aspell/*.so mrk,', '/{usr/,}lib{,32,64}/** mrk,', '/{usr/,}lib{,32,64}/**.so* mrk,', '/usr/lib/aspell/some.so mrk,'] ), (['/foo/log', 'w'], ['/foo/log w,'] ), ] def _run_test(self, params, expected): self.createTmpdir() #copy the local profiles to the test directory self.profile_dir = '%s/profiles' % self.tmpdir shutil.copytree('../../profiles/apparmor.d/', self.profile_dir, symlinks=True) # load the abstractions we need in the test apparmor.aa.profiledir = self.profile_dir apparmor.aa.load_include('abstractions/base') apparmor.aa.load_include('abstractions/bash') apparmor.aa.load_include('abstractions/enchant') apparmor.aa.load_include('abstractions/aspell') # add some user_globs ('(N)ew') to simulate a professional aa-logprof user (and to make sure that part of the code also gets tested) apparmor.aa.user_globs['/usr/share/common*/foo/*'] = AARE('/usr/share/common*/foo/*', True) apparmor.aa.user_globs['/no/thi*ng'] = AARE('/no/thi*ng', True) profile = apparmor.aa.ProfileStorage('/test', '/test', 'test-aa.py') profile['include']['abstractions/base'] = True profile['include']['abstractions/bash'] = True profile['include']['abstractions/enchant'] = True # includes abstractions/aspell profile['file'].add(FileRule.parse('owner /usr/share/common-licenses/** w,')) profile['file'].add(FileRule.parse('/dev/null rwk,')) profile['file'].add(FileRule.parse('/foo/bar rwix,')) profile['file'].add(FileRule.parse('/foo/log a,')) # will be replaced with '/foo/log w,' (not 'wa') rule_obj = FileRule(params[0], params[1], None, FileRule.ALL, owner=False, log_event=True) proposals = propose_file_rules(profile, rule_obj) self.assertEqual(proposals, expected) class AaTest_propose_file_rules_with_absolute_includes(AATest): tests = [ # log event path and perms expected proposals (['/not/found/anywhere', 'r'], ['/not/found/anywhere r,']), (['/dev/null', 'w'], ['/dev/null rw,']), (['/some/random/include', 'r'], ['/some/random/include rw,']), (['/some/other/include', 'w'], ['/some/other/* rw,', '/some/other/inc* rw,', '/some/other/include rw,']), ] def _run_test(self, params, expected): self.createTmpdir() #copy the local profiles to the test directory self.profile_dir = '%s/profiles' % self.tmpdir shutil.copytree('../../profiles/apparmor.d/', self.profile_dir, symlinks=True) # load the abstractions we need in the test apparmor.aa.profiledir = self.profile_dir apparmor.aa.load_include('abstractions/base') abs_include1 = write_file(self.tmpdir, 'test-abs1', "/some/random/include rw,") apparmor.aa.load_include(abs_include1) abs_include2 = write_file(self.tmpdir, 'test-abs2', "/some/other/* rw,") apparmor.aa.load_include(abs_include2) abs_include3 = write_file(self.tmpdir, 'test-abs3', "/some/other/inc* rw,") apparmor.aa.load_include(abs_include3) profile = apparmor.aa.ProfileStorage('/test', '/test', 'test-aa.py') profile['include']['abstractions/base'] = False profile['include'][abs_include1] = False profile['include'][abs_include2] = False profile['include'][abs_include3] = False rule_obj = FileRule(params[0], params[1], None, FileRule.ALL, owner=False, log_event=True) proposals = propose_file_rules(profile, rule_obj) self.assertEqual(proposals, expected) class AaTest_nonexistent_includes(AATest): def test_bad_includes(self): tests = [ "/nonexistent/absolute/path", "nonexistent/relative/path", ] for i in tests: with self.assertRaises(AppArmorException): apparmor.aa.load_include(i) setup_aa(apparmor.aa) setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-regex_matches.py0000644000175000017500000007665613502024172017515 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import apparmor.aa as aa import unittest from common_test import AATest, setup_all_loops, setup_aa from apparmor.common import AppArmorBug, AppArmorException from apparmor.regex import ( strip_parenthesis, strip_quotes, parse_profile_start_line, re_match_include, RE_PROFILE_START, RE_PROFILE_DBUS, RE_PROFILE_CAP, RE_PROFILE_PTRACE, RE_PROFILE_SIGNAL ) class AARegexTest(AATest): def _run_test(self, params, expected): return _regex_test(self, params, expected) class AANamedRegexTest(AATest): def _run_test(self, line, expected): '''Run a line through self.regex.search() and verify the result Keyword arguments: line -- the line to search expected -- False if the search isn't expected to match or, if the search is expected to match, a tuple of expected match groups. ''' matches = self.regex.search(line) if not expected: self.assertFalse(matches) return self.assertTrue(matches) for exp in expected: match = matches.group(exp) if match: match = match self.assertEqual(match, expected[exp], 'Group %s mismatch in rule %s' % (exp,line)) class AARegexHasComma(AATest): '''Tests for apparmor.aa.RE_RULE_HAS_COMMA''' def _check(self, line, expected=True): result = aa.RE_RULE_HAS_COMMA.search(line) if expected: self.assertTrue(result, 'Couldn\'t find a comma in "%s"' % line) else: self.assertEqual(None, result, 'Found an unexpected comma in "%s"' % line) regex_has_comma_testcases = [ ('dbus send%s', 'simple'), ('dbus (r, w, bind, eavesdrop)%s', 'embedded parens 01'), ('dbus (r, w,, bind, eavesdrop) %s', 'embedded parens 02'), ('dbus (r, w,, ) %s', 'embedded parens 03'), ('dbus () %s', 'empty parens'), ('member={Hello,AddMatch,RemoveMatch,GetNameOwner,NameHasOwner,StartServiceByName} %s ', 'embedded curly braces 01'), ('member={Hello,,,,,,AddMatch,,,NameHasOwner,StartServiceByName} %s ', 'embedded curly braces 02'), ('member={,Hello,,,,,,AddMatch,,,NameHasOwner,} %s ', 'embedded curly braces 03'), ('member={} %s ', 'empty curly braces'), ('dbus send%s# this is a comment', 'comment 01'), ('dbus send%s# this is a comment,', 'comment 02'), ('audit "/tmp/foo, bar" rw%s', 'quotes 01'), ('audit "/tmp/foo, bar" rw%s # comment', 'quotes 02'), ('audit "/tmp/foo, # bar" rw%s', 'comment embedded in quote 01'), ('audit "/tmp/foo, # bar" rw%s # comment', 'comment embedded in quote 02'), # lifted from parser/tst/simple_tests/vars/vars_alternation_3.sd ('/does/not/@{BAR},exist,notexist} r%s', 'partial alternation'), ('signal%s', 'bare signal'), ('signal receive%s', 'simple signal'), ('signal (send, receive)%s', 'embedded parens signal 01'), ('signal (send, receive) set=(hup, quit)%s', 'embedded parens signal 02'), ('ptrace%s', 'bare ptrace'), ('ptrace trace%s', 'simple ptrace'), ('ptrace (tracedby, readby)%s', 'embedded parens ptrace 01'), ('ptrace (trace) peer=/usr/bin/foo%s', 'embedded parens ptrace 02'), ('pivot_root%s', 'bare pivot_root'), ('pivot_root /old%s', 'pivot_root with old'), ('pivot_root /old new%s', 'pivot_root with new'), ('pivot_root /old /new -> child%s', 'pivot_root with child'), ('unix%s', 'bare unix'), ('unix create%s', 'simple unix'), ('peer=(addr=@abad1dea,label=a_profile) %s ', 'peer parens and comma'), ('type=stream%s', 'unix type'), ('unix (connect, receive, send)%s', 'unix perms'), # the following fail due to inadequacies in the regex # ('dbus (r, w, %s', 'incomplete dbus action'), # ('member="{Hello,AddMatch,RemoveMatch, %s', 'incomplete {} regex'), # also invalid policy # ('member={Hello,AddMatch,RemoveMatch, %s', 'incomplete {} regex'), # also invalid policy when trailing comma exists # the following passes the tests, but variable declarations are # odd in that they *don't* allow trailing commas; commas at the end # of the line need to be quoted. # ('@{BAR}={bar,baz,blort %s', 'tricksy variable declaration') # ('@{BAR}="{bar,baz,blort," %s', 'tricksy variable declaration') # The following fails the no comma test, but is invalid # ('@{BAR}={bar,baz,blort, %s', 'tricksy variable declaration') # The following fails the comma test, because it's really a no comma situation # ('@{BAR}="{bar,baz,blort%s" ', 'tricksy variable declaration') ] def setup_has_comma_testcases(): i = 0 for (test_string, description) in regex_has_comma_testcases: i += 1 def stub_test_comma(self, test_string=test_string): self._check(test_string % ',') def stub_test_no_comma(self, test_string=test_string): self._check(test_string % ' ', False) stub_test_comma.__doc__ = "test %s (w/comma)" % (description) stub_test_no_comma.__doc__ = "test %s (no comma)" % (description) setattr(AARegexHasComma, 'test_comma_%d' % (i), stub_test_comma) setattr(AARegexHasComma, 'test_no_comma_%d' % (i), stub_test_no_comma) class AARegexSplitComment(AATest): '''Tests for RE_HAS_COMMENT_SPLIT''' def _check(self, line, expected, comment=None, not_comment=None): result = aa.RE_HAS_COMMENT_SPLIT.search(line) if expected: self.assertTrue(result, 'Couldn\'t find a comment in "%s"' % line) self.assertEqual(result.group('comment'), comment, 'Expected comment "%s", got "%s"' % (comment, result.group('comment'))) self.assertEqual(result.group('not_comment'), not_comment, 'Expected not comment "%s", got "%s"' % (not_comment, result.group('not_comment'))) else: self.assertEqual(None, result, 'Found an unexpected comment "%s" in "%s"' % ("" if result is None else result.group('comment'), line )) # Tuples of (string, expected result), where expected result is False if # the string should not be considered as having a comment, or a second # tuple of the not comment and comment sections split apart regex_split_comment_testcases = [ ('dbus send # this is a comment', ('dbus send ', '# this is a comment')), ('dbus send member=no_comment', False), ('dbus send member=no_comment, ', False), ('audit "/tmp/foo, # bar" rw', False), ('audit "/tmp/foo, # bar" rw # comment', ('audit "/tmp/foo, # bar" rw ', '# comment')), ('file,', False), ('file, # bare', ('file, ', '# bare')), ('file /tmp/foo rw, # read-write', ('file /tmp/foo rw, ', '# read-write')), ('signal, # comment', ('signal, ', '# comment')), ('signal receive set=(usr1 usr2) peer=foo,', False), ('ptrace, # comment', ('ptrace, ', '# comment')), ('ptrace (trace read) peer=/usr/bin/foo,', False), ('pivot_root, # comment', ('pivot_root, ', '# comment')), ('pivot_root /old /new -> child,', False), ] def setup_split_comment_testcases(): i = 0 for (test_string, result) in regex_split_comment_testcases: i += 1 def stub_test(self, test_string=test_string, result=result): if result is False: self._check(test_string, False) else: self._check(test_string, True, not_comment=result[0], comment=result[1]) stub_test.__doc__ = "test '%s'" % (test_string) setattr(AARegexSplitComment, 'test_split_comment_%d' % (i), stub_test) def _regex_test(self, line, expected): '''Run a line through self.regex.search() and verify the result Keyword arguments: line -- the line to search expected -- False if the search isn't expected to match or, if the search is expected to match, a tuple of expected match groups with all of the strings stripped ''' result = self.regex.search(line) if not expected: self.assertFalse(result) return self.assertTrue(result) groups = result.groups() self.assertEqual(len(groups), len(expected)) for (i, group) in enumerate(groups): if group: group = group.strip() self.assertEqual(group, expected[i], 'Group %d mismatch in rule %s' % (i,line)) class AARegexCapability(AARegexTest): '''Tests for RE_PROFILE_CAP''' def AASetup(self): self.regex = RE_PROFILE_CAP tests = [ (' capability net_raw,', (None, None, 'net_raw', 'net_raw', None)), ('capability net_raw , ', (None, None, 'net_raw', 'net_raw', None)), (' capability,', (None, None, None, None, None)), (' capability , ', (None, None, None, None, None)), (' capabilitynet_raw,', False) ] class AARegexDbus(AARegexTest): '''Tests for RE_PROFILE_DBUS''' def AASetup(self): self.regex = RE_PROFILE_DBUS tests = [ (' dbus,', (None, None, 'dbus,', None, None)), (' audit dbus,', ('audit', None, 'dbus,', None, None)), (' dbus send member=no_comment,', (None, None, 'dbus send member=no_comment,', 'send member=no_comment', None)), (' dbus send member=no_comment, # comment', (None, None, 'dbus send member=no_comment,', 'send member=no_comment', '# comment')), (' dbusdriver,', False), (' audit dbusdriver,', False), ] class AARegexMount(AARegexTest): '''Tests for RE_PROFILE_MOUNT''' def AASetup(self): self.regex = aa.RE_PROFILE_MOUNT tests = [ (' mount,', (None, None, 'mount,', 'mount', None, None)), (' audit mount,', ('audit', None, 'mount,', 'mount', None, None)), (' umount,', (None, None, 'umount,', 'umount', None, None)), (' audit umount,', ('audit', None, 'umount,', 'umount', None, None)), (' unmount,', (None, None, 'unmount,', 'unmount', None, None)), (' audit unmount,', ('audit', None, 'unmount,', 'unmount', None, None)), (' remount,', (None, None, 'remount,', 'remount', None, None)), (' deny remount,', (None, 'deny', 'remount,', 'remount', None, None)), (' mount, # comment', (None, None, 'mount,', 'mount', None, '# comment')), (' mountain,', False), (' audit mountain,', False), ] class AARegexSignal(AARegexTest): '''Tests for RE_PROFILE_SIGNAL''' def AASetup(self): self.regex = RE_PROFILE_SIGNAL tests = [ (' signal,', (None, None, 'signal,', None, None)), (' audit signal,', ('audit', None, 'signal,', None, None)), (' signal receive,', (None, None, 'signal receive,', 'receive', None)), (' signal (send, receive),', (None, None, 'signal (send, receive),', '(send, receive)', None)), (' audit signal (receive),', ('audit', None, 'signal (receive),', '(receive)', None)), (' signal (send, receive) set=(usr1 usr2),', (None, None, 'signal (send, receive) set=(usr1 usr2),', '(send, receive) set=(usr1 usr2)', None)), (' signal send set=(hup, quit) peer=/usr/sbin/daemon,', (None, None, 'signal send set=(hup, quit) peer=/usr/sbin/daemon,', 'send set=(hup, quit) peer=/usr/sbin/daemon', None)), (' signalling,', False), (' audit signalling,', False), (' signalling receive,', False), ] class AARegexPtrace(AARegexTest): '''Tests for RE_PROFILE_PTRACE''' def AASetup(self): self.regex = RE_PROFILE_PTRACE tests = [ # audit allow rule rule details comment (' ptrace,', (None, None, 'ptrace,', None, None)), (' audit ptrace,', ('audit', None, 'ptrace,', None, None)), (' ptrace trace,', (None, None, 'ptrace trace,', 'trace', None)), (' ptrace (tracedby, readby),', (None, None, 'ptrace (tracedby, readby),', '(tracedby, readby)', None)), (' audit ptrace (read),', ('audit', None, 'ptrace (read),', '(read)', None)), (' ptrace trace peer=/usr/sbin/daemon,', (None, None, 'ptrace trace peer=/usr/sbin/daemon,', 'trace peer=/usr/sbin/daemon', None)), (' ptraceback,', False), (' audit ptraceback,', False), (' ptraceback trace,', False), ] class AARegexPivotRoot(AARegexTest): '''Tests for RE_PROFILE_PIVOT_ROOT''' def AASetup(self): self.regex = aa.RE_PROFILE_PIVOT_ROOT tests = [ (' pivot_root,', (None, None, 'pivot_root,', None)), (' audit pivot_root,', ('audit', None, 'pivot_root,', None)), (' pivot_root oldroot=/new/old,', (None, None, 'pivot_root oldroot=/new/old,', None)), (' pivot_root oldroot=/new/old /new,', (None, None, 'pivot_root oldroot=/new/old /new,', None)), (' pivot_root oldroot=/new/old /new -> child,', (None, None, 'pivot_root oldroot=/new/old /new -> child,', None)), (' audit pivot_root oldroot=/new/old /new -> child,', ('audit', None, 'pivot_root oldroot=/new/old /new -> child,', None)), ('pivot_root', False), # comma missing ('pivot_rootbeer,', False), ('pivot_rootbeer , ', False), ('pivot_rootbeer, # comment', False), ('pivot_rootbeer /new, ', False), ('pivot_rootbeer /new, # comment', False), ] class AARegexUnix(AARegexTest): '''Tests for RE_PROFILE_UNIX''' def AASetup(self): self.regex = aa.RE_PROFILE_UNIX tests = [ (' unix,', (None, None, 'unix,', None)), (' audit unix,', ('audit', None, 'unix,', None)), (' unix accept,', (None, None, 'unix accept,', None)), (' allow unix connect,', (None, 'allow', 'unix connect,', None)), (' audit allow unix bind,', ('audit', 'allow', 'unix bind,', None)), (' deny unix bind,', (None, 'deny', 'unix bind,', None)), ('unix peer=(label=@{profile_name}),', (None, None, 'unix peer=(label=@{profile_name}),', None)), ('unix (receive) peer=(label=unconfined),', (None, None, 'unix (receive) peer=(label=unconfined),', None)), (' unix (getattr, shutdown) peer=(addr=none),', (None, None, 'unix (getattr, shutdown) peer=(addr=none),', None)), ('unix (connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/dbus-*"),', (None, None, 'unix (connect, receive, send) type=stream peer=(label=unconfined,addr="@/tmp/dbus-*"),', None)), ('unixlike', False), ('deny unixlike,', False), ] class AANamedRegexProfileStart_2(AANamedRegexTest): '''Tests for RE_PROFILE_START''' def AASetup(self): self.regex = RE_PROFILE_START tests = [ ('/bin/foo ', False), # no '{' ('/bin/foo /bin/bar', False), # missing 'profile' keyword ('profile {', False), # no attachment (' profile foo bar /foo {', False), # missing quotes around "foo bar" ('bin/foo {', False), # not starting with '/' ('"bin/foo" {', False), # not starting with '/', quoted version (' /foo {', { 'plainprofile': '/foo', 'namedprofile': None, 'attachment': None, 'flags': None, 'comment': None }), (' "/foo" {', { 'plainprofile': '"/foo"', 'namedprofile': None, 'attachment': None, 'flags': None, 'comment': None }), (' profile /foo {', { 'plainprofile': None, 'namedprofile': '/foo', 'attachment': None, 'flags': None, 'comment': None }), (' profile "/foo" {', { 'plainprofile': None, 'namedprofile': '"/foo"', 'attachment': None, 'flags': None, 'comment': None }), (' profile foo /foo {', { 'plainprofile': None, 'namedprofile': 'foo', 'attachment': '/foo', 'flags': None, 'comment': None }), (' profile foo /foo (audit) {', { 'plainprofile': None, 'namedprofile': 'foo', 'attachment': '/foo', 'flags': 'audit', 'comment': None }), (' profile "foo" "/foo" {', { 'plainprofile': None, 'namedprofile': '"foo"', 'attachment': '"/foo"', 'flags': None, 'comment': None }), (' profile "foo bar" /foo {', { 'plainprofile': None, 'namedprofile': '"foo bar"', 'attachment': '/foo', 'flags': None, 'comment': None }), (' /foo (complain) {', { 'plainprofile': '/foo', 'namedprofile': None, 'attachment': None, 'flags': 'complain', 'comment': None }), (' /foo flags=(complain) {', { 'plainprofile': '/foo', 'namedprofile': None, 'attachment': None, 'flags': 'complain', 'comment': None }), (' /foo (complain) { # x', { 'plainprofile': '/foo', 'namedprofile': None, 'attachment': None, 'flags': 'complain', 'comment': '# x'}), (' /foo flags = ( complain ){#',{ 'plainprofile': '/foo', 'namedprofile': None, 'attachment': None, 'flags': ' complain ', 'comment': '#'}), (' @{foo} {', { 'plainprofile': '@{foo}', 'namedprofile': None, 'attachment': None, 'flags': None, 'comment': None }), (' profile @{foo} {', { 'plainprofile': None, 'namedprofile': '@{foo}', 'attachment': None, 'flags': None, 'comment': None }), (' profile @{foo} /bar {', { 'plainprofile': None, 'namedprofile': '@{foo}', 'attachment': '/bar', 'flags': None, 'comment': None }), (' profile foo @{bar} {', { 'plainprofile': None, 'namedprofile': 'foo', 'attachment': '@{bar}', 'flags': None, 'comment': None }), (' profile @{foo} @{bar} {', { 'plainprofile': None, 'namedprofile': '@{foo}', 'attachment': '@{bar}', 'flags': None, 'comment': None }), (' /foo {', { 'plainprofile': '/foo', 'namedprofile': None, 'leadingspace': ' ' }), ('/foo {', { 'plainprofile': '/foo', 'namedprofile': None, 'leadingspace': '' }), (' profile foo {', { 'plainprofile': None, 'namedprofile': 'foo', 'leadingspace': ' ' }), ('profile foo {', { 'plainprofile': None, 'namedprofile': 'foo', 'leadingspace': '' }), ] class Test_parse_profile_start_line(AATest): tests = [ (' /foo {', { 'profile': '/foo', 'profile_keyword': False, 'plainprofile': '/foo', 'namedprofile': None, 'attachment': None, 'flags': None, 'comment': None }), (' "/foo" {', { 'profile': '/foo', 'profile_keyword': False, 'plainprofile': '/foo', 'namedprofile': None, 'attachment': None, 'flags': None, 'comment': None }), (' profile /foo {', { 'profile': '/foo', 'profile_keyword': True, 'plainprofile': None, 'namedprofile': '/foo', 'attachment': None, 'flags': None, 'comment': None }), (' profile "/foo" {', { 'profile': '/foo', 'profile_keyword': True, 'plainprofile': None, 'namedprofile': '/foo', 'attachment': None, 'flags': None, 'comment': None }), (' profile foo /foo {', { 'profile': 'foo', 'profile_keyword': True, 'plainprofile': None, 'namedprofile': 'foo', 'attachment': '/foo', 'flags': None, 'comment': None }), (' profile foo /foo (audit) {', { 'profile': 'foo', 'profile_keyword': True, 'plainprofile': None, 'namedprofile': 'foo', 'attachment': '/foo', 'flags': 'audit', 'comment': None }), (' profile "foo" "/foo" {', { 'profile': 'foo', 'profile_keyword': True, 'plainprofile': None, 'namedprofile': 'foo', 'attachment': '/foo', 'flags': None, 'comment': None }), (' profile "foo bar" /foo {', { 'profile': 'foo bar', 'profile_keyword': True, 'plainprofile': None, 'namedprofile': 'foo bar','attachment': '/foo', 'flags': None, 'comment': None }), (' /foo (complain) {', { 'profile': '/foo', 'profile_keyword': False, 'plainprofile': '/foo', 'namedprofile': None, 'attachment': None, 'flags': 'complain', 'comment': None }), (' /foo flags=(complain) {', { 'profile': '/foo', 'profile_keyword': False, 'plainprofile': '/foo', 'namedprofile': None, 'attachment': None, 'flags': 'complain', 'comment': None }), (' /foo flags = ( complain ){', { 'profile': '/foo', 'profile_keyword': False, 'plainprofile': '/foo', 'namedprofile': None, 'attachment': None, 'flags': ' complain ', 'comment': None }), (' /foo (complain) { # x', { 'profile': '/foo', 'profile_keyword': False, 'plainprofile': '/foo', 'namedprofile': None, 'attachment': None, 'flags': 'complain', 'comment': '# x'}), (' /foo {', { 'profile': '/foo', 'plainprofile': '/foo', 'namedprofile': None, 'leadingspace': ' ' }), ('/foo {', { 'profile': '/foo', 'plainprofile': '/foo', 'namedprofile': None, 'leadingspace': None }), (' profile foo {', { 'profile': 'foo', 'plainprofile': None, 'namedprofile': 'foo', 'leadingspace': ' ' }), ('profile foo {', { 'profile': 'foo', 'plainprofile': None, 'namedprofile': 'foo', 'leadingspace': None }), (' @{foo} {', { 'profile': '@{foo}', 'plainprofile': '@{foo}', 'namedprofile': None, 'attachment': None, 'flags': None, 'comment': None }), (' profile @{foo} {', { 'profile': '@{foo}', 'plainprofile': None, 'namedprofile': '@{foo}', 'attachment': None, 'flags': None, 'comment': None }), (' profile @{foo} /bar {', { 'profile': '@{foo}', 'plainprofile': None, 'namedprofile': '@{foo}', 'attachment': '/bar', 'flags': None, 'comment': None }), (' profile foo @{bar} {', { 'profile': 'foo', 'plainprofile': None, 'namedprofile': 'foo', 'attachment': '@{bar}', 'flags': None, 'comment': None }), (' profile @{foo} @{bar} {', { 'profile': '@{foo}', 'plainprofile': None, 'namedprofile': '@{foo}', 'attachment': '@{bar}', 'flags': None, 'comment': None }), ] def _run_test(self, line, expected): matches = parse_profile_start_line(line, 'somefile') self.assertTrue(matches) for exp in expected: self.assertEqual(matches[exp], expected[exp], 'Group %s mismatch in rule %s' % (exp,line)) class TestInvalid_parse_profile_start_line(AATest): tests = [ ('/bin/foo ', False), # no '{' ('/bin/foo /bin/bar', False), # missing 'profile' keyword ('profile {', False), # no attachment (' profile foo bar /foo {', False), # missing quotes around "foo bar" ] def _run_test(self, line, expected): with self.assertRaises(AppArmorBug): parse_profile_start_line(line, 'somefile') class Test_re_match_include(AATest): tests = [ ('#include ', 'abstractions/base' ), # magic path ('#include # comment', 'abstractions/base' ), ('#include#comment', 'abstractions/base' ), (' #include ', 'abstractions/base' ), ('#include "/foo/bar"', '/foo/bar' ), # absolute path ('#include "/foo/bar" # comment', '/foo/bar' ), ('#include "/foo/bar"#comment', '/foo/bar' ), (' #include "/foo/bar" ', '/foo/bar' ), ('include ', 'abstractions/base' ), # magic path ('include # comment', 'abstractions/base' ), ('include#comment', 'abstractions/base' ), (' include ', 'abstractions/base' ), ('include "/foo/bar"', '/foo/bar' ), # absolute path ('include "/foo/bar" # comment', '/foo/bar' ), ('include "/foo/bar"#comment', '/foo/bar' ), (' include "/foo/bar" ', '/foo/bar' ), (' some #include ', None, ), # non-matching (' /etc/fstab r,', None, ), ('/usr/include r,', None, ), ('/include r,', None, ), ] def _run_test(self, params, expected): self.assertEqual(re_match_include(params), expected) class TestInvalid_re_match_include(AATest): tests = [ ('#include <>', AppArmorException ), # '#include' ('#include < >', AppArmorException ), ('#include ""', AppArmorException ), ('#include " "', AppArmorException ), ('#include', AppArmorException ), ('#include ', AppArmorException ), ('#include "foo"', AppArmorException ), # LP: 1738880 (relative) ('#include "foo" # comment', AppArmorException ), ('#include "foo"#comment', AppArmorException ), (' #include "foo" ', AppArmorException ), ('#include "foo/bar"', AppArmorException ), ('#include "foo/bar" # comment', AppArmorException ), ('#include "foo/bar"#comment', AppArmorException ), (' #include "foo/bar" ', AppArmorException ), ('#include foo', AppArmorException ), # LP: 1738879 (no quotes) ('#include foo/bar', AppArmorException ), ('#include /foo/bar', AppArmorException ), ('#include foo bar', AppArmorException ), # LP: 1738877 (space in name) ('#include foo bar/baz', AppArmorException ), ('#include "foo bar"', AppArmorException ), ('#include /foo bar', AppArmorException ), ('#include "/foo bar"', AppArmorException ), ('#include "foo bar/baz"', AppArmorException ), ('include <>', AppArmorException ), # 'include' ('include < >', AppArmorException ), ('include ""', AppArmorException ), ('include " "', AppArmorException ), ('include', AppArmorException ), ('include ', AppArmorException ), ('include "foo"', AppArmorException ), # LP: 1738880 (relative) ('include "foo" # comment', AppArmorException ), ('include "foo"#comment', AppArmorException ), (' include "foo" ', AppArmorException ), ('include "foo/bar"', AppArmorException ), ('include "foo/bar" # comment', AppArmorException ), ('include "foo/bar"#comment', AppArmorException ), (' include "foo/bar" ', AppArmorException ), ('include foo', AppArmorException ), # LP: 1738879 (no quotes) ('include foo/bar', AppArmorException ), ('include /foo/bar', AppArmorException ), ('include foo bar', AppArmorException ), # LP: 1738877 (space in name) ('include foo bar/baz', AppArmorException ), ('include "foo bar"', AppArmorException ), ('include /foo bar', AppArmorException ), ('include "/foo bar"', AppArmorException ), ('include "foo bar/baz"', AppArmorException ), ] def _run_test(self, params, expected): with self.assertRaises(expected): re_match_include(params) class TestStripParenthesis(AATest): tests = [ ('foo', 'foo' ), ('(foo)', 'foo' ), ('( foo )', 'foo' ), ('(foo', '(foo' ), ('foo )', 'foo )' ), ('foo ()', 'foo ()' ), ('()', '' ), ('( )', '' ), ('(())', '()' ), (' (foo)', '(foo)' ), # parenthesis not first char, whitespace stripped nevertheless ('(foo) ', '(foo)' ), # parenthesis not last char, whitespace stripped nevertheless ] def _run_test(self, params, expected): self.assertEqual(strip_parenthesis(params), expected) class TestStripQuotes(AATest): def test_strip_quotes_01(self): self.assertEqual('foo', strip_quotes('foo')) def test_strip_quotes_02(self): self.assertEqual('foo', strip_quotes('"foo"')) def test_strip_quotes_03(self): self.assertEqual('"foo', strip_quotes('"foo')) def test_strip_quotes_04(self): self.assertEqual('foo"', strip_quotes('foo"')) def test_strip_quotes_05(self): self.assertEqual('', strip_quotes('""')) def test_strip_quotes_06(self): self.assertEqual('foo"bar', strip_quotes('foo"bar')) def test_strip_quotes_07(self): self.assertEqual('foo"bar', strip_quotes('"foo"bar"')) def test_strip_quotes_08(self): self.assertEqual('"""foo"bar"""', strip_quotes('""""foo"bar""""')) setup_aa(aa) setup_all_loops(__name__) if __name__ == '__main__': # these two are not converted to a tests[] loop yet setup_has_comma_testcases() setup_split_comment_testcases() unittest.main(verbosity=1) apparmor-2.13.3/utils/test/severity_broken.db0000644000175000017500000002450513502024172017053 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2002-2005 Novell/SUSE # Copyright (C) 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ # Allow this process to 0wn the machine: CAP_SYS_ADMIN 10 CAP_SYS_CHROOT 10 CAP_SYS_MODULE CAP_SYS_PTRACE 10 CAP_SYS_RAWIO 10 CAP_MAC_ADMIN 10 CAP_MAC_OVERRIDE 10 # Allow other processes to 0wn the machine: CAP_SETPCAP 9 CAP_SETFCAP 9 CAP_CHOWN 9 CAP_FSETID 9 CAP_MKNOD 9 CAP_LINUX_IMMUTABLE 9 CAP_DAC_OVERRIDE 9 CAP_SETGID 9 CAP_SETUID 9 CAP_FOWNER 9 # Denial of service, bypass audit controls, information leak CAP_SYS_TIME 8 CAP_NET_ADMIN 8 CAP_SYS_RESOURCE 8 CAP_KILL 8 CAP_IPC_OWNER 8 CAP_SYS_PACCT 8 CAP_SYS_BOOT 8 CAP_NET_BIND_SERVICE 8 CAP_NET_RAW 8 CAP_SYS_NICE 8 CAP_LEASE 8 CAP_IPC_LOCK 8 CAP_SYS_TTY_CONFIG 8 CAP_AUDIT_CONTROL 8 CAP_AUDIT_WRITE 8 CAP_SYSLOG 8 CAP_WAKE_ALARM 8 CAP_BLOCK_SUSPEND 8 CAP_DAC_READ_SEARCH 7 # unused CAP_NET_BROADCAST 0 # filename r w x # 'hard drives' are generally 4 10 0 /**/lost+found/** 5 5 0 /boot/** 7 10 0 /etc/passwd* 4 8 0 /etc/group* 4 8 0 /etc/shadow* 7 9 0 /etc/shadow* 7 9 0 /home/*/.ssh/** 7 9 0 /home/*/.gnupg/** 5 7 0 /home/** 4 6 0 /srv/** 4 6 0 /proc/** 6 9 0 /proc/sys/kernel/hotplug 2 10 0 /proc/sys/kernel/modprobe 2 10 0 /proc/kallsyms 7 0 0 /sys/** 4 8 0 /sys/power/state 2 8 0 /sys/firmware/** 2 10 0 /dev/pts/* 8 9 0 /dev/ptmx 8 9 0 /dev/pty* 8 9 0 /dev/null 0 0 0 /dev/adbmouse 3 8 0 /dev/ataraid 9 10 0 /dev/zero 0 0 0 /dev/agpgart* 8 10 0 /dev/aio 3 3 0 /dev/cbd/* 5 5 0 /dev/cciss/* 4 10 0 /dev/capi* 4 6 0 /dev/cfs0 4 10 0 /dev/compaq/* 4 10 0 /dev/cdouble* 4 8 0 /dev/cpu** 5 5 0 /dev/cpu**microcode 1 10 0 /dev/double* 4 8 0 /dev/hd* 4 10 0 /dev/sd* 4 10 0 /dev/ida/* 4 10 0 /dev/input/* 4 8 0 /dev/mapper/control 4 10 0 /dev/*mem 8 10 0 /dev/loop* 4 10 0 /dev/lp* 0 4 0 /dev/md* 4 10 0 /dev/msr 4 10 0 /dev/nb* 4 10 0 /dev/ram* 8 10 0 /dev/rd/* 4 10 0 /dev/*random 3 1 0 /dev/sbpcd* 4 0 0 /dev/rtc 6 0 0 /dev/sd* 4 10 0 /dev/sc* 4 10 0 /dev/sg* 4 10 0 /dev/st* 4 10 0 /dev/snd/* 3 8 0 /dev/usb/mouse* 4 6 0 /dev/usb/hid* 4 6 0 /dev/usb/tty* 4 6 0 /dev/tty* 8 9 0 /dev/stderr 0 0 0 /dev/stdin 0 0 0 /dev/stdout 0 0 0 /dev/ubd* 4 10 0 /dev/usbmouse* 4 6 0 /dev/userdma 8 10 0 /dev/vcs* 8 9 0 /dev/xta* 4 10 0 /dev/zero 0 0 0 /dev/inittcl 8 10 0 /dev/log 5 7 0 /etc/fstab 3 8 0 /etc/mtab 3 5 0 /etc/SuSEconfig/* 1 8 0 /etc/X11/* 2 7 0 /etc/X11/xinit/* 2 8 0 /etc/SuSE-release 1 5 0 /etc/issue* 1 3 0 /etc/motd 1 3 0 /etc/aliases.d/* 1 7 0 /etc/cron* 1 9 0 /etc/cups/* 2 7 0 /etc/default/* 3 8 0 /etc/init.d/* 1 10 0 /etc/permissions.d/* 1 8 0 /etc/ppp/* 2 6 0 /etc/ppp/*secrets 8 6 0 /etc/profile.d/* 1 8 0 /etc/skel/* 0 7 0 /etc/sysconfig/* 4 10 0 /etc/xinetd.d/* 1 9 0 /etc/termcap/* 1 4 0 /etc/ld.so.* 1 9 0 /etc/pam.d/* 3 9 0 /etc/udev/* 3 9 0 /etc/insserv.conf 3 6 0 /etc/security/* 1 9 0 /etc/securetty 0 7 0 /etc/sudoers 4 9 0 /etc/hotplug/* 2 10 0 /etc/xinitd.conf 1 9 0 /etc/gpm/* 2 10 0 /etc/ssl/** 2 7 0 /etc/shadow* 5 9 0 /etc/bash.bashrc 1 9 0 /etc/csh.cshrc 1 9 0 /etc/csh.login 1 9 0 /etc/inittab 1 10 0 /etc/profile* 1 9 0 /etc/shells 1 5 0 /etc/alternatives 1 6 0 /etc/sysctl.conf 3 7 0 /etc/dev.d/* 1 8 0 /etc/manpath.config 1 6 0 /etc/permissions* 1 8 0 /etc/evms.conf 3 8 0 /etc/exports 3 8 0 /etc/samba/* 5 8 0 /etc/ssh/* 3 8 0 /etc/ssh/ssh_host_*key 8 8 0 /etc/krb5.conf 4 8 0 /etc/ntp.conf 3 8 0 /etc/auto.* 3 8 0 /etc/postfix/* 3 7 0 /etc/postfix/*passwd* 6 7 0 /etc/postfix/*cert* 6 7 0 /etc/foomatic/* 3 5 0 /etc/printcap 3 5 0 /etc/youservers 4 9 0 /etc/grub.conf 7 10 0 /etc/modules.conf 4 10 0 /etc/resolv.conf 2 7 0 /etc/apache2/** 3 7 0 /etc/apache2/**ssl** 7 7 0 /etc/subdomain.d/** 6 10 0 /etc/apparmor.d/** 6 10 0 /etc/apparmor/** 6 10 0 /var/log/** 3 8 0 /var/adm/SuSEconfig/** 3 8 0 /var/adm/** 3 7 0 /var/lib/rpm/** 4 8 0 /var/run/nscd/* 3 3 0 /var/run/.nscd_socket 3 3 0 /usr/share/doc/** 1 1 0 /usr/share/man/** 3 5 0 /usr/X11/man/** 3 5 0 /usr/share/info/** 2 4 0 /usr/share/java/** 2 5 0 /usr/share/locale/** 2 4 0 /usr/share/sgml/** 2 4 0 /usr/share/YaST2/** 3 9 0 /usr/share/ghostscript/** 3 5 0 /usr/share/terminfo/** 1 8 0 /usr/share/latex2html/** 2 4 0 /usr/share/cups/** 5 6 0 /usr/share/susehelp/** 2 6 0 /usr/share/susehelp/cgi-bin/** 3 7 7 /usr/share/zoneinfo/** 2 7 0 /usr/share/zsh/** 3 6 0 /usr/share/vim/** 3 8 0 /usr/share/groff/** 3 7 0 /usr/share/vnc/** 3 8 0 /usr/share/wallpapers/** 2 4 0 /usr/X11** 3 8 5 /usr/X11*/bin/XFree86 3 8 8 /usr/X11*/bin/Xorg 3 8 8 /usr/X11*/bin/sux 3 8 8 /usr/X11*/bin/xconsole 3 7 7 /usr/X11*/bin/xhost 3 7 7 /usr/X11*/bin/xauth 3 7 7 /usr/X11*/bin/ethereal 3 6 8 /usr/lib/ooo-** 3 6 5 /usr/lib/lsb/** 2 8 8 /usr/lib/pt_chwon 2 8 5 /usr/lib/tcl** 2 5 3 /usr/lib/lib*so* 3 8 4 /usr/lib/iptables/* 2 8 2 /usr/lib/perl5/** 4 10 6 /usr/lib/*/perl/* 4 10 6 /usr/lib/*/perl5/* 4 10 6 /usr/lib/gconv/* 4 7 4 /usr/lib/locale/** 4 8 0 /usr/lib/jvm/** 5 7 5 /usr/lib/sasl*/** 5 8 4 /usr/lib/jvm-exports/** 5 7 5 /usr/lib/jvm-private/** 5 7 5 /usr/lib/python*/** 5 7 5 /usr/lib/libkrb5* 4 8 4 /usr/lib/postfix/* 4 7 4 /usr/lib/rpm/** 4 8 6 /usr/lib/rpm/gnupg/** 4 9 0 /usr/lib/apache2** 4 7 4 /usr/lib/mailman/** 4 6 4 /usr/bin/ldd 1 7 4 /usr/bin/netcat 5 7 8 /usr/bin/clear 2 6 3 /usr/bin/reset 2 6 3 /usr/bin/tput 2 6 3 /usr/bin/tset 2 6 3 /usr/bin/file 2 6 3 /usr/bin/ftp 3 7 5 /usr/bin/busybox 4 8 6 /usr/bin/rbash 4 8 5 /usr/bin/screen 3 6 5 /usr/bin/getfacl 3 7 4 /usr/bin/setfacl 3 7 9 /usr/bin/*awk* 3 7 7 /usr/bin/sudo 2 9 10 /usr/bin/lsattr 2 6 5 /usr/bin/chattr 2 7 8 /usr/bin/sed 3 7 6 /usr/bin/grep 2 7 2 /usr/bin/chroot 2 6 10 /usr/bin/dircolors 2 9 3 /usr/bin/cut 2 7 2 /usr/bin/du 2 7 3 /usr/bin/env 2 7 2 /usr/bin/head 2 7 2 /usr/bin/tail 2 7 2 /usr/bin/install 2 8 4 /usr/bin/link 2 6 4 /usr/bin/logname 2 6 2 /usr/bin/md5sum 2 8 3 /usr/bin/mkfifo 2 6 10 /usr/bin/nice 2 7 7 /usr/bin/nohup 2 7 7 /usr/bin/printf 2 7 1 /usr/bin/readlink 2 7 3 /usr/bin/seq 2 7 1 /usr/bin/sha1sum 2 8 3 /usr/bin/shred 2 7 3 /usr/bin/sort 2 7 3 /usr/bin/split 2 7 3 /usr/bin/stat 2 7 4 /usr/bin/sum 2 8 3 /usr/bin/tac 2 7 3 /usr/bin/tail 3 8 4 /usr/bin/tee 2 7 3 /usr/bin/test 2 8 4 /usr/bin/touch 2 7 3 /usr/bin/tr 2 8 3 /usr/bin/tsort 2 7 3 /usr/bin/tty 2 7 3 /usr/bin/unexpand 2 7 3 /usr/bin/uniq 2 7 3 /usr/bin/unlink 2 8 4 /usr/bin/uptime 2 7 3 /usr/bin/users 2 8 4 /usr/bin/vdir 2 8 4 /usr/bin/wc 2 7 3 /usr/bin/who 2 8 4 /usr/bin/whoami 2 8 4 /usr/bin/yes 1 6 1 /usr/bin/ed 2 7 5 /usr/bin/red 2 7 4 /usr/bin/find 2 8 5 /usr/bin/xargs 2 7 5 /usr/bin/ispell 2 7 4 /usr/bin/a2p 2 7 5 /usr/bin/perlcc 2 7 5 /usr/bin/perldoc 2 7 5 /usr/bin/pod2* 2 7 5 /usr/bin/prove 2 7 5 /usr/bin/perl 2 10 7 /usr/bin/perl* 2 10 7 /usr/bin/suidperl 2 8 8 /usr/bin/csh 2 8 8 /usr/bin/tcsh 2 8 8 /usr/bin/tree 2 6 5 /usr/bin/last 2 7 5 /usr/bin/lastb 2 7 5 /usr/bin/utmpdump 2 6 5 /usr/bin/alsamixer 2 6 8 /usr/bin/amixer 2 6 8 /usr/bin/amidi 2 6 8 /usr/bin/aoss 2 6 8 /usr/bin/aplay 2 6 8 /usr/bin/aplaymidi 2 6 8 /usr/bin/arecord 2 6 8 /usr/bin/arecordmidi 2 6 8 /usr/bin/aseqnet 2 6 8 /usr/bin/aserver 2 6 8 /usr/bin/iecset 2 6 8 /usr/bin/rview 2 6 5 /usr/bin/ex 2 7 5 /usr/bin/enscript 2 6 5 /usr/bin/genscript 2 6 5 /usr/bin/xdelta 2 6 5 /usr/bin/edit 2 6 5 /usr/bin/vimtutor 2 6 5 /usr/bin/rvim 2 6 5 /usr/bin/vim 2 8 7 /usr/bin/vimdiff 2 8 7 /usr/bin/aspell 2 6 5 /usr/bin/xxd 2 6 5 /usr/bin/spell 2 6 5 /usr/bin/eqn 2 6 5 /usr/bin/eqn2graph 2 6 5 /usr/bin/word-list-compress 2 6 4 /usr/bin/afmtodit 2 6 4 /usr/bin/hpf2dit 2 6 4 /usr/bin/geqn 2 6 4 /usr/bin/grn 2 6 4 /usr/bin/grodvi 2 6 4 /usr/bin/groff 2 6 5 /usr/bin/groffer 2 6 4 /usr/bin/grolj4 2 6 4 /usr/bin/grotty 2 6 4 /usr/bin/gtbl 2 6 4 /usr/bin/pic2graph 2 6 4 /usr/bin/indxbib 2 6 4 /usr/bin/lkbib 2 6 4 /usr/bin/lookbib 2 6 4 /usr/bin/mmroff 2 6 4 /usr/bin/neqn 2 6 4 /usr/bin/pfbtops 2 6 4 /usr/bin/pic 2 6 4 /usr/bin/tfmtodit 2 6 4 /usr/bin/tbl 2 6 4 /usr/bin/post-grohtml 2 6 4 /usr/bin/pre-grohtml 2 6 4 /usr/bin/refer 2 6 4 /usr/bin/soelim 2 6 4 /usr/bin/disable-paste 2 6 6 /usr/bin/troff 2 6 4 /usr/bin/strace-graph 2 6 4 /usr/bin/gpm-root 2 6 7 /usr/bin/hltest 2 6 7 /usr/bin/mev 2 6 6 /usr/bin/mouse-test 2 6 6 /usr/bin/strace 2 8 9 /usr/bin/scsiformat 2 7 10 /usr/bin/lsscsi 2 7 7 /usr/bin/scsiinfo 2 7 7 /usr/bin/sg_* 2 7 7 /usr/bin/build-classpath 2 6 6 /usr/bin/build-classpath-directory 2 6 6 /usr/bin/build-jar-repository 2 6 6 /usr/bin/diff-jars 2 6 6 /usr/bin/jvmjar 2 6 6 /usr/bin/rebuild-jar-repository 2 6 6 /usr/bin/scriptreplay 2 6 5 /usr/bin/cal 2 6 3 /usr/bin/chkdupexe 2 6 5 /usr/bin/col 2 6 4 /usr/bin/colcrt 2 6 4 /usr/bin/colrm 2 6 3 /usr/bin/column 2 6 4 /usr/bin/cytune 2 6 6 /usr/bin/ddate 2 6 3 /usr/bin/fdformat 2 6 6 /usr/bin/getopt 2 8 6 /usr/bin/hexdump 2 6 4 /usr/bin/hostid 2 6 4 /usr/bin/ipcrm 2 7 7 /usr/bin/ipcs 2 7 6 /usr/bin/isosize 2 6 4 /usr/bin/line 2 6 4 /usr/bin/look 2 6 5 /usr/bin/mcookie 2 7 5 /usr/bin/mesg 2 6 4 /usr/bin/namei 2 6 5 /usr/bin/rename 2 6 5 /usr/bin/renice 2 6 7 /usr/bin/rev 2 6 5 /usr/bin/script 2 6 6 /usr/bin/ChangeSymlinks 2 8 8 /usr/bin/setfdprm 2 6 7 /usr/bin/setsid 2 6 3 /usr/bin/setterm 2 6 5 /usr/bin/tailf 2 6 4 /usr/bin/time 2 6 4 /usr/bin/ul 2 6 4 /usr/bin/wall 2 6 5 /usr/bin/whereis 2 6 4 /usr/bin/which 2 6 3 /usr/bin/c_rehash 2 7 6 /usr/bin/openssl 2 8 6 /usr/bin/lsdev 2 6 5 /usr/bin/procinfo 2 6 5 /usr/bin/socklist 2 6 5 /usr/bin/filesize 2 6 3 /usr/bin/linkto 2 6 3 /usr/bin/mkinfodir 2 6 5 /usr/bin/old 2 6 4 /usr/bin/rpmlocate 2 6 5 /usr/bin/safe-rm 2 8 6 /usr/bin/safe-rmdir 2 8 6 /usr/bin/setJava 2 6 1 /usr/bin/vmstat 2 6 4 /usr/bin/top 2 6 6 /usr/bin/pinentry* 2 7 6 /usr/bin/free 2 8 4 /usr/bin/pmap 2 6 5 /usr/bin/slabtop 2 6 4 /usr/bin/tload 2 6 4 /usr/bin/watch 2 6 3 /usr/bin/w 2 6 4 /usr/bin/pstree.x11 2 6 4 /usr/bin/pstree 2 6 4 /usr/bin/snice 2 6 6 /usr/bin/skill 2 6 7 /usr/bin/pgrep 2 6 4 /usr/bin/killall 2 6 7 /usr/bin/curl 2 7 7 /usr/bin/slptool 2 7 8 /usr/bin/ldap* 2 7 7 /usr/bin/whatis 2 7 5 apparmor-2.13.3/utils/test/test-profile-list.py0000644000175000017500000001035413502024172017267 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2018 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import unittest from common_test import AATest, setup_all_loops from apparmor.common import AppArmorBug, AppArmorException from apparmor.profile_list import ProfileList class TestAdd(AATest): def AASetup(self): self.pl = ProfileList() def testEmpty(self): self.assertEqual(self.pl.profile_names, {}) self.assertEqual(self.pl.attachments, {}) def testAdd_1(self): self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') self.assertEqual(self.pl.profile_names, {'foo': '/etc/apparmor.d/bin.foo'}) self.assertEqual(self.pl.attachments, {'/bin/foo': '/etc/apparmor.d/bin.foo'}) def testAdd_2(self): self.pl.add('/etc/apparmor.d/bin.foo', None, '/bin/foo') self.assertEqual(self.pl.profile_names, {}) self.assertEqual(self.pl.attachments, {'/bin/foo': '/etc/apparmor.d/bin.foo'}) def testAdd_3(self): self.pl.add('/etc/apparmor.d/bin.foo', 'foo', None) self.assertEqual(self.pl.profile_names, {'foo': '/etc/apparmor.d/bin.foo'}) self.assertEqual(self.pl.attachments, {}) def testAddError_1(self): with self.assertRaises(AppArmorBug): self.pl.add('', 'foo', '/bin/foo') # no filename def testAddError_2(self): with self.assertRaises(AppArmorBug): self.pl.add('/etc/apparmor.d/bin.foo', None, None) # neither attachment or profile name def testAddError_twice_1(self): self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') with self.assertRaises(AppArmorException): self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') def testAddError_twice_2(self): self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') with self.assertRaises(AppArmorException): self.pl.add('/etc/apparmor.d/bin.foo', 'foo', None) def testAddError_twice_3(self): self.pl.add('/etc/apparmor.d/bin.foo', None, '/bin/foo') with self.assertRaises(AppArmorException): self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') def testAddError_twice_4(self): self.pl.add('/etc/apparmor.d/bin.foo', None, '/bin/foo') with self.assertRaises(AppArmorException): self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') def testAddError_twice_5(self): self.pl.add('/etc/apparmor.d/bin.foo', 'foo', None) with self.assertRaises(AppArmorException): self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') class TestFilename_from_profile_name(AATest): tests = [ ('foo', '/etc/apparmor.d/bin.foo'), ('/bin/foo', None), ('bar', None), ] def AASetup(self): self.pl = ProfileList() self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') def _run_test(self, params, expected): self.assertEqual(self.pl.filename_from_profile_name(params), expected) class TestFilename_from_attachment(AATest): tests = [ ('/bin/foo', '/etc/apparmor.d/bin.foo'), ('/bin/baz', '/etc/apparmor.d/bin.baz'), ('/bin/foobar', '/etc/apparmor.d/bin.foobar'), ('@{foo}', None), # XXX variables not supported yet (and @{foo} isn't defined in this test) ('/bin/404', None), ] def AASetup(self): self.pl = ProfileList() self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo') self.pl.add('/etc/apparmor.d/bin.baz', 'baz', '/bin/ba*') self.pl.add('/etc/apparmor.d/bin.foobar', 'foobar', '/bin/foo{bar,baz}') def _run_test(self, params, expected): self.assertEqual(self.pl.filename_from_attachment(params), expected) def test_non_path_attachment(self): with self.assertRaises(AppArmorBug): self.pl.filename_from_attachment('foo') setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-capability.py0000644000175000017500000010740013502024172016776 0ustar jjjj#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2014 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import unittest from common_test import AATest, setup_all_loops from apparmor.rule.capability import CapabilityRule, CapabilityRuleset from apparmor.rule import BaseRule import apparmor.severity as severity from apparmor.common import AppArmorException, AppArmorBug, hasher from apparmor.logparser import ReadLog from apparmor.translations import init_translation _ = init_translation() # --- tests for single CapabilityRule --- # class CapabilityTest(AATest): def _compare_obj_with_rawrule(self, rawrule, expected): obj = CapabilityRule.parse(rawrule) self.assertTrue(CapabilityRule.match(rawrule)) self.assertEqual(rawrule.strip(), obj.raw_rule) self._compare_obj(obj, expected) def _compare_obj(self, obj, expected): self.assertEqual(expected['allow_keyword'], obj.allow_keyword) self.assertEqual(expected['audit'], obj.audit) self.assertEqual(expected['capability'], obj.capability) self.assertEqual(expected['all_caps'], obj.all_caps) self.assertEqual(expected['deny'], obj.deny) self.assertEqual(expected['comment'], obj.comment) def test_cap_allow_all(self): self._compare_obj_with_rawrule("capability,", { 'allow_keyword': False, 'deny': False, 'audit': False, 'capability': set(), 'all_caps': True, 'comment': "", }) def test_cap_allow_sys_admin(self): self._compare_obj_with_rawrule("capability sys_admin,", { 'allow_keyword': False, 'deny': False, 'audit': False, 'capability': {'sys_admin'}, 'all_caps': False, 'comment': "", }) def test_cap_deny_sys_admin(self): self._compare_obj_with_rawrule(" deny capability sys_admin, # some comment", { 'allow_keyword': False, 'deny': True, 'audit': False, 'capability': {'sys_admin'}, 'all_caps': False, 'comment': " # some comment", }) def test_cap_multi(self): self._compare_obj_with_rawrule("capability sys_admin dac_override,", { 'allow_keyword': False, 'deny': False, 'audit': False, 'capability': {'sys_admin', 'dac_override'}, 'all_caps': False, 'comment': "", }) # Template for test_cap_* functions # def test_cap_(self): # self._compare_obj_with_rawrule("capability,", { # 'allow_keyword': False, # 'deny': False, # 'audit': False, # 'capability': set(), # (or {'foo'} if not empty) # 'all_caps': False, # 'comment': "", # }) def test_cap_from_log(self): parser = ReadLog('', '', '', '') event = 'type=AVC msg=audit(1415403814.628:662): apparmor="ALLOWED" operation="capable" profile="/bin/ping" pid=15454 comm="ping" capability=13 capname="net_raw"' parsed_event = parser.parse_event(event) self.assertEqual(parsed_event, { 'request_mask': None, 'denied_mask': None, 'error_code': 0, 'magic_token': 0, 'parent': 0, 'profile': '/bin/ping', 'operation': 'capable', 'resource': None, 'info': None, 'aamode': 'PERMITTING', 'time': 1415403814, 'active_hat': None, 'pid': 15454, 'task': 0, 'attr': None, 'name2': None, 'name': 'net_raw', 'family': None, 'protocol': None, 'sock_type': None, }) obj = CapabilityRule(parsed_event['name'], log_event=parsed_event) self._compare_obj(obj, { 'allow_keyword': False, 'deny': False, 'audit': False, 'capability': {'net_raw'}, 'all_caps': False, 'comment': "", }) self.assertEqual(obj.get_raw(1), ' capability net_raw,') # def test_cap_from_invalid_log(self): # parser = ReadLog('', '', '', '') # # invalid log entry, name= should contain the capability name # event = 'type=AVC msg=audit(1415403814.628:662): apparmor="ALLOWED" operation="capable" profile="/bin/ping" pid=15454 comm="ping" capability=13 capname=""' # # parsed_event = parser.parse_event(event) # # obj = CapabilityRule() # # with self.assertRaises(AppArmorBug): # obj.set_log(parsed_event) # # with self.assertRaises(AppArmorBug): # obj.get_raw(1) # # def test_cap_from_non_cap_log(self): # parser = ReadLog('', '', '', '') # # log entry for different rule type # event = 'type=AVC msg=audit(1415403814.973:667): apparmor="ALLOWED" operation="setsockopt" profile="/home/sys-tmp/ping" pid=15454 comm="ping" lport=1 family="inet" sock_type="raw" protocol=1' # # parsed_event = parser.parse_event(event) # # obj = CapabilityRule() # # with self.assertRaises(AppArmorBug): # obj.set_log(parsed_event) # # with self.assertRaises(AppArmorBug): # obj.get_raw(1) def test_cap_from_init_01(self): obj = CapabilityRule('chown') self._compare_obj(obj, { 'allow_keyword': False, 'deny': False, 'audit': False, 'capability': {'chown'}, 'all_caps': False, 'comment': "", }) def test_cap_from_init_02(self): obj = CapabilityRule(['chown']) self._compare_obj(obj, { 'allow_keyword': False, 'deny': False, 'audit': False, 'capability': {'chown'}, 'all_caps': False, 'comment': "", }) def test_cap_from_init_03(self): obj = CapabilityRule('chown', audit=True, deny=True) self._compare_obj(obj, { 'allow_keyword': False, 'deny': True, 'audit': True, 'capability': {'chown'}, 'all_caps': False, 'comment': "", }) def test_cap_from_init_04(self): obj = CapabilityRule(['chown', 'fsetid'], deny=True) self._compare_obj(obj, { 'allow_keyword': False, 'deny': True, 'audit': False, 'capability': {'chown', 'fsetid'}, 'all_caps': False, 'comment': "", }) class InvalidCapabilityTest(AATest): def _check_invalid_rawrule(self, rawrule): obj = None with self.assertRaises(AppArmorException): obj = CapabilityRule(CapabilityRule.parse(rawrule)) self.assertFalse(CapabilityRule.match(rawrule)) self.assertIsNone(obj, 'CapbilityRule handed back an object unexpectedly') def test_invalid_cap_missing_comma(self): self._check_invalid_rawrule('capability') # missing comma def test_invalid_cap_non_CapabilityRule(self): self._check_invalid_rawrule('network,') # not a capability rule def test_empty_cap_set(self): obj = CapabilityRule('chown') obj.capability.clear() # no capability set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) def test_empty_cap_list(self): with self.assertRaises(AppArmorBug): CapabilityRule([]) def test_no_cap_list_arg(self): with self.assertRaises(TypeError): CapabilityRule() def test_space_cap(self): with self.assertRaises(AppArmorBug): CapabilityRule(' ') # the whitespace capability ;-) def test_space_list_1(self): with self.assertRaises(AppArmorBug): CapabilityRule([' ', ' ', ' ']) # the whitespace capability ;-) def test_space_list_2(self): with self.assertRaises(AppArmorBug): CapabilityRule(['chown', ' ', 'setgid']) # includes the whitespace capability ;-) def test_wrong_type_for_cap(self): with self.assertRaises(AppArmorBug): CapabilityRule(dict()) class WriteCapabilityTest(AATest): def _check_write_rule(self, rawrule, cleanrule): obj = CapabilityRule.parse(rawrule) clean = obj.get_clean() raw = obj.get_raw() self.assertTrue(CapabilityRule.match(rawrule)) self.assertEqual(cleanrule.strip(), clean, 'unexpected clean rule') self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule') def test_write_all(self): self._check_write_rule(' capability , # foo ', 'capability, # foo') def test_write_sys_admin(self): self._check_write_rule(' audit capability sys_admin,', 'audit capability sys_admin,') def test_write_sys_multi(self): self._check_write_rule(' deny capability sys_admin audit_write,# foo bar', 'deny capability audit_write sys_admin, # foo bar') def test_write_manually(self): obj = CapabilityRule(['ptrace', 'audit_write'], allow_keyword=True) expected = ' allow capability audit_write ptrace,' self.assertEqual(expected, obj.get_clean(2), 'unexpected clean rule') self.assertEqual(expected, obj.get_raw(2), 'unexpected raw rule') class CapabilityCoveredTest(AATest): def _is_covered(self, obj, rule_to_test): self.assertTrue(CapabilityRule.match(rule_to_test)) return obj.is_covered(CapabilityRule.parse(rule_to_test)) def _is_covered_exact(self, obj, rule_to_test): self.assertTrue(CapabilityRule.match(rule_to_test)) return obj.is_covered(CapabilityRule.parse(rule_to_test), True, True) def _is_equal(self, obj, rule_to_test, strict): self.assertTrue(CapabilityRule.match(rule_to_test)) return obj.is_equal(CapabilityRule.parse(rule_to_test), strict) def test_covered_single(self): obj = CapabilityRule.parse('capability sys_admin,') self.assertTrue(self._is_covered(obj, 'capability sys_admin,')) self.assertFalse(self._is_covered(obj, 'audit capability sys_admin,')) self.assertFalse(self._is_covered(obj, 'audit capability,')) self.assertFalse(self._is_covered(obj, 'capability chown,')) self.assertFalse(self._is_covered(obj, 'capability,')) def test_covered_audit(self): obj = CapabilityRule.parse('audit capability sys_admin,') self.assertTrue(self._is_covered(obj, 'capability sys_admin,')) self.assertTrue(self._is_covered(obj, 'audit capability sys_admin,')) self.assertFalse(self._is_covered(obj, 'audit capability,')) self.assertFalse(self._is_covered(obj, 'capability chown,')) self.assertFalse(self._is_covered(obj, 'capability,')) def test_covered_check_audit(self): obj = CapabilityRule.parse('audit capability sys_admin,') self.assertFalse(self._is_covered_exact(obj, 'capability sys_admin,')) self.assertTrue(self._is_covered_exact(obj, 'audit capability sys_admin,')) self.assertFalse(self._is_covered_exact(obj, 'audit capability,')) self.assertFalse(self._is_covered_exact(obj, 'capability chown,')) self.assertFalse(self._is_covered_exact(obj, 'capability,')) def test_equal(self): obj = CapabilityRule.parse('capability sys_admin,') self.assertTrue(self._is_equal(obj, 'capability sys_admin,', True)) self.assertFalse(self._is_equal(obj, 'allow capability sys_admin,', True)) self.assertFalse(self._is_equal(obj, 'allow capability sys_admin,', True)) self.assertFalse(self._is_equal(obj, 'audit capability sys_admin,', True)) self.assertTrue(self._is_equal(obj, 'capability sys_admin,', False)) self.assertTrue(self._is_equal(obj, 'allow capability sys_admin,', False)) self.assertFalse(self._is_equal(obj, 'audit capability sys_admin,', False)) def test_covered_multi(self): obj = CapabilityRule.parse('capability audit_write sys_admin,') self.assertTrue(self._is_covered(obj, 'capability sys_admin,')) self.assertTrue(self._is_covered(obj, 'capability audit_write,')) self.assertTrue(self._is_covered(obj, 'capability audit_write sys_admin,')) self.assertTrue(self._is_covered(obj, 'capability sys_admin audit_write,')) self.assertFalse(self._is_covered(obj, 'audit capability,')) self.assertFalse(self._is_covered(obj, 'capability chown,')) self.assertFalse(self._is_covered(obj, 'capability,')) def test_covered_all(self): obj = CapabilityRule.parse('capability,') self.assertTrue(self._is_covered(obj, 'capability sys_admin,')) self.assertTrue(self._is_covered(obj, 'capability audit_write,')) self.assertTrue(self._is_covered(obj, 'capability audit_write sys_admin,')) self.assertTrue(self._is_covered(obj, 'capability sys_admin audit_write,')) self.assertTrue(self._is_covered(obj, 'capability,')) self.assertFalse(self._is_covered(obj, 'audit capability,')) def test_covered_deny(self): obj = CapabilityRule.parse('capability sys_admin,') self.assertTrue(self._is_covered(obj, 'capability sys_admin,')) self.assertFalse(self._is_covered(obj, 'audit deny capability sys_admin,')) self.assertFalse(self._is_covered(obj, 'deny capability sys_admin,')) self.assertFalse(self._is_covered(obj, 'capability chown,')) self.assertFalse(self._is_covered(obj, 'capability,')) def test_covered_deny_2(self): obj = CapabilityRule.parse('deny capability sys_admin,') self.assertTrue(self._is_covered(obj, 'deny capability sys_admin,')) self.assertFalse(self._is_covered(obj, 'audit deny capability sys_admin,')) self.assertFalse(self._is_covered(obj, 'capability sys_admin,')) self.assertFalse(self._is_covered(obj, 'deny capability chown,')) self.assertFalse(self._is_covered(obj, 'deny capability,')) def test_invalid_is_covered(self): obj = CapabilityRule.parse('capability sys_admin,') testobj = BaseRule() # different type with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_borked_obj_is_covered(self): obj = CapabilityRule.parse('capability sys_admin,') testobj = CapabilityRule('chown') testobj.capability.clear() with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_invalid_is_equal(self): obj = CapabilityRule.parse('capability sys_admin,') testobj = BaseRule() # different type with self.assertRaises(AppArmorBug): obj.is_equal(testobj) def test_empty_init(self): # add to internal set instead of using .set_* (which overwrites the internal set) to make sure obj and obj2 use separate storage obj = CapabilityRule('fsetid') obj2 = CapabilityRule('fsetid') obj.capability.add('sys_admin') obj2.capability.add('ptrace') self.assertTrue(self._is_covered(obj, 'capability sys_admin,')) self.assertFalse(self._is_covered(obj, 'capability ptrace,')) self.assertFalse(self._is_covered(obj2, 'capability sys_admin,')) self.assertTrue(self._is_covered(obj2, 'capability ptrace,')) class CapabiliySeverityTest(AATest): tests = [ ('fsetid', 9), ('dac_read_search', 7), (['fsetid', 'dac_read_search'], 9), (CapabilityRule.ALL, 10), ('foo', 'unknown'), ] def _run_test(self, params, expected): sev_db = severity.Severity('severity.db', 'unknown') obj = CapabilityRule(params) rank = obj.severity(sev_db) self.assertEqual(rank, expected) class CapabilityLogprofHeaderTest(AATest): tests = [ ('capability,', [ _('Capability'), _('ALL'), ]), ('capability chown,', [ _('Capability'), 'chown', ]), ('capability chown fsetid,', [ _('Capability'), 'chown fsetid', ]), ('audit capability,', [_('Qualifier'), 'audit', _('Capability'), _('ALL'), ]), ('deny capability chown,', [_('Qualifier'), 'deny', _('Capability'), 'chown', ]), ('allow capability chown fsetid,', [_('Qualifier'), 'allow', _('Capability'), 'chown fsetid', ]), ('audit deny capability,', [_('Qualifier'), 'audit deny', _('Capability'), _('ALL'), ]), ] def _run_test(self, params, expected): obj = CapabilityRule._parse(params) self.assertEqual(obj.logprof_header(), expected) # --- tests for CapabilityRuleset --- # class CapabilityRulesTest(AATest): def test_empty_ruleset(self): ruleset = CapabilityRuleset() ruleset_2 = CapabilityRuleset() self.assertEqual([], ruleset.get_raw(2)) self.assertEqual([], ruleset.get_clean(2)) self.assertEqual([], ruleset_2.get_raw(2)) self.assertEqual([], ruleset_2.get_clean(2)) def test_ruleset_1(self): ruleset = CapabilityRuleset() rules = [ 'capability sys_admin,', 'capability chown,', ] expected_raw = [ 'capability sys_admin,', 'capability chown,', '', ] expected_clean = [ 'capability chown,', 'capability sys_admin,', '', ] for rule in rules: ruleset.add(CapabilityRule.parse(rule)) self.assertEqual(expected_raw, ruleset.get_raw()) self.assertEqual(expected_clean, ruleset.get_clean()) def test_ruleset_2(self): ruleset = CapabilityRuleset() rules = [ 'capability chown,', 'allow capability sys_admin,', 'deny capability chgrp, # example comment', ] expected_raw = [ ' capability chown,', ' allow capability sys_admin,', ' deny capability chgrp, # example comment', '', ] expected_clean = [ ' deny capability chgrp, # example comment', '', ' allow capability sys_admin,', ' capability chown,', '', ] for rule in rules: ruleset.add(CapabilityRule.parse(rule)) self.assertEqual(expected_raw, ruleset.get_raw(1)) self.assertEqual(expected_clean, ruleset.get_clean(1)) def test_ruleset_add(self): rule = CapabilityRule('chgrp', comment=' # example comment') ruleset = CapabilityRuleset() ruleset.add(rule) expected_raw = [ ' capability chgrp, # example comment', '', ] expected_clean = expected_raw self.assertEqual(expected_raw, ruleset.get_raw(1)) self.assertEqual(expected_clean, ruleset.get_clean(1)) class CapabilityRulesCoveredTest(AATest): def AASetup(self): self.ruleset = CapabilityRuleset() rules = [ 'capability chown,', 'capability setuid setgid,', 'allow capability sys_admin,', 'audit capability kill,', 'deny capability chgrp, # example comment', ] for rule in rules: self.ruleset.add(CapabilityRule.parse(rule)) def test_ruleset_is_covered_1(self): self.assertTrue(self.ruleset.is_covered(CapabilityRule.parse('capability chown,'))) def test_ruleset_is_covered_2(self): self.assertTrue(self.ruleset.is_covered(CapabilityRule.parse('capability sys_admin,'))) def test_ruleset_is_covered_3(self): self.assertTrue(self.ruleset.is_covered(CapabilityRule.parse('allow capability sys_admin,'))) def test_ruleset_is_covered_4(self): self.assertTrue(self.ruleset.is_covered(CapabilityRule.parse('capability setuid,'))) def test_ruleset_is_covered_5(self): self.assertTrue(self.ruleset.is_covered(CapabilityRule.parse('allow capability setgid,'))) def test_ruleset_is_covered_6(self): self.assertTrue(self.ruleset.is_covered(CapabilityRule.parse('capability setgid setuid,'))) def test_ruleset_is_covered_7(self): pass # self.assertTrue(self.ruleset.is_covered(CapabilityRule.parse('capability sys_admin chown,'))) # fails because it is split over two rule objects internally def test_ruleset_is_covered_8(self): self.assertTrue(self.ruleset.is_covered(CapabilityRule.parse('capability kill,'))) def test_ruleset_is_covered_9(self): self.assertFalse(self.ruleset.is_covered(CapabilityRule.parse('deny capability chown,'))) def test_ruleset_is_covered_10(self): self.assertFalse(self.ruleset.is_covered(CapabilityRule.parse('deny capability sys_admin,'))) def test_ruleset_is_covered_11(self): self.assertFalse(self.ruleset.is_covered(CapabilityRule.parse('deny capability sys_admin chown,'))) def test_ruleset_is_covered_12(self): self.assertFalse(self.ruleset.is_covered(CapabilityRule.parse('deny capability setgid,'))) def test_ruleset_is_covered_13(self): self.assertFalse(self.ruleset.is_covered(CapabilityRule.parse('deny capability kill,'))) def test_ruleset_is_covered_14(self): self.assertFalse(self.ruleset.is_covered(CapabilityRule.parse('audit capability chown,'))) def test_ruleset_is_covered_15(self): self.assertFalse(self.ruleset.is_covered(CapabilityRule.parse('audit capability sys_admin,'))) def test_ruleset_is_covered_16(self): self.assertFalse(self.ruleset.is_covered(CapabilityRule.parse('audit capability sys_admin chown,'))) def test_ruleset_is_covered_17(self): self.assertFalse(self.ruleset.is_covered(CapabilityRule.parse('audit capability setgid,'))) def test_ruleset_is_covered_18(self): self.assertTrue(self.ruleset.is_covered(CapabilityRule.parse('audit capability kill,'))) def test_ruleset_is_covered_19(self): self.assertTrue(self.ruleset.is_covered(CapabilityRule.parse('deny capability chgrp,'))) def test_ruleset_is_covered_20(self): self.assertFalse(self.ruleset.is_covered(CapabilityRule.parse('audit deny capability chgrp,'))) def test_ruleset_is_covered_21(self): self.assertFalse(self.ruleset.is_covered(CapabilityRule.parse('audit capability chgrp,'))) def test_ruleset_is_covered_22(self): self.assertFalse(self.ruleset.is_covered(CapabilityRule.parse('capability chgrp,'))) def test_ruleset_is_covered_23(self): self.assertTrue(self.ruleset.is_covered(CapabilityRule.parse('capability chgrp,'), check_allow_deny=False)) def test_ruleset_is_covered_24(self): self.assertFalse(self.ruleset.is_covered(CapabilityRule.parse('deny capability chown,'), check_allow_deny=False)) # XXX - disabling these until we decide whether or not checking whether # a log is covered by rules should be a separate entry point, possibly # handling the log structure directly, or whether coverage should be # solely based on Rule objects and marshaling of a log message into a # Rule object should occur outside of the Rule classes themselves. # # def _test_log_covered(self, expected, capability): # event_base = 'type=AVC msg=audit(1415403814.628:662): apparmor="ALLOWED" operation="capable" profile="/bin/ping" pid=15454 comm="ping" capability=13 capname="%s"' # parser = ReadLog('', '', '', '') # self.assertEqual(expected, self.ruleset.is_log_covered(parser.parse_event(event_base%capability))) # # def test_ruleset_is_log_covered_1(self): # self._test_log_covered(False, 'net_raw') # def test_ruleset_is_log_covered_2(self): # self._test_log_covered(True, 'chown') # def test_ruleset_is_log_covered_3(self): # self._test_log_covered(True, 'sys_admin') # def test_ruleset_is_log_covered_4(self): # self._test_log_covered(True, 'kill') # def test_ruleset_is_log_covered_5(self): # self._test_log_covered(False, 'chgrp') # def test_ruleset_is_log_covered_6(self): # event_base = 'type=AVC msg=audit(1415403814.628:662): apparmor="ALLOWED" operation="capable" profile="/bin/ping" pid=15454 comm="ping" capability=13 capname="%s"' # # parser = ReadLog('', '', '', '') # self.assertEqual(True, self.ruleset.is_log_covered(parser.parse_event(event_base%'chgrp'), False)) # ignores allow/deny class CapabilityGlobTest(AATest): def AASetup(self): self.ruleset = CapabilityRuleset() def test_glob(self): self.assertEqual(self.ruleset.get_glob('capability net_raw,'), 'capability,') def test_glob_ext(self): with self.assertRaises(NotImplementedError): self.ruleset.get_glob_ext('capability net_raw,') class CapabilityDeleteTest(AATest): def AASetup(self): self.ruleset = CapabilityRuleset() rules = [ 'capability chown,', 'allow capability sys_admin,', 'deny capability chgrp, # example comment', ] for rule in rules: self.ruleset.add(CapabilityRule.parse(rule)) def test_delete(self): expected_raw = [ ' capability chown,', ' deny capability chgrp, # example comment', '', ] expected_clean = [ ' deny capability chgrp, # example comment', '', ' capability chown,', '', ] self.ruleset.delete(CapabilityRule(['sys_admin'])) self.assertEqual(expected_raw, self.ruleset.get_raw(1)) self.assertEqual(expected_clean, self.ruleset.get_clean(1)) def test_delete_with_allcaps(self): expected_raw = [ ' capability chown,', ' deny capability chgrp, # example comment', ' capability,', '', ] expected_clean = [ ' deny capability chgrp, # example comment', '', ' capability chown,', ' capability,', '', ] self.ruleset.add(CapabilityRule(CapabilityRule.ALL)) self.ruleset.delete(CapabilityRule('sys_admin')) self.assertEqual(expected_raw, self.ruleset.get_raw(1)) self.assertEqual(expected_clean, self.ruleset.get_clean(1)) def test_delete_with_multi(self): expected_raw = [ ' capability chown,', ' allow capability sys_admin,', ' deny capability chgrp, # example comment', '', ] expected_clean = [ ' deny capability chgrp, # example comment', '', ' allow capability sys_admin,', ' capability chown,', '', ] self.ruleset.add(CapabilityRule(['audit_read', 'audit_write'])) self.ruleset.delete(CapabilityRule(['audit_read', 'audit_write'])) self.assertEqual(expected_raw, self.ruleset.get_raw(1)) self.assertEqual(expected_clean, self.ruleset.get_clean(1)) def test_delete_with_multi_2(self): self.ruleset.add(CapabilityRule(['audit_read', 'audit_write'])) with self.assertRaises(AppArmorBug): # XXX ideally delete_raw should remove audit_read from the "capability audit_read audit_write," ruleset # but that's quite some work to cover a corner case. self.ruleset.delete(CapabilityRule('audit_read')) def test_delete_raw_notfound(self): with self.assertRaises(AppArmorBug): self.ruleset.delete(CapabilityRule('audit_write')) def test_delete_duplicates(self): inc = CapabilityRuleset() rules = [ 'capability chown,', 'deny capability chgrp, # example comment', ] for rule in rules: inc.add(CapabilityRule.parse(rule)) expected_raw = [ ' allow capability sys_admin,', '', ] expected_clean = expected_raw self.assertEqual(self.ruleset.delete_duplicates(inc), 2) self.assertEqual(expected_raw, self.ruleset.get_raw(1)) self.assertEqual(expected_clean, self.ruleset.get_clean(1)) def test_delete_duplicates_2(self): inc = CapabilityRuleset() rules = [ 'capability audit_write,', 'capability chgrp, # example comment', ] for rule in rules: inc.add(CapabilityRule.parse(rule)) expected_raw = [ ' capability chown,', ' allow capability sys_admin,', ' deny capability chgrp, # example comment', '', ] expected_clean = [ ' deny capability chgrp, # example comment', '', ' allow capability sys_admin,', ' capability chown,', '', ] self.assertEqual(self.ruleset.delete_duplicates(inc), 0) self.assertEqual(expected_raw, self.ruleset.get_raw(1)) self.assertEqual(expected_clean, self.ruleset.get_clean(1)) def test_delete_duplicates_3(self): self.ruleset.add(CapabilityRule.parse('audit capability dac_override,')) inc = CapabilityRuleset() rules = [ 'capability dac_override,', ] for rule in rules: inc.add(CapabilityRule.parse(rule)) expected_raw = [ ' capability chown,', ' allow capability sys_admin,', ' deny capability chgrp, # example comment', ' audit capability dac_override,', '', ] expected_clean = [ ' deny capability chgrp, # example comment', '', ' allow capability sys_admin,', ' audit capability dac_override,', ' capability chown,', '', ] self.assertEqual(self.ruleset.delete_duplicates(inc), 0) self.assertEqual(expected_raw, self.ruleset.get_raw(1)) self.assertEqual(expected_clean, self.ruleset.get_clean(1)) def test_delete_duplicates_4(self): inc = CapabilityRuleset() rules = [ 'capability,', ] for rule in rules: inc.add(CapabilityRule.parse(rule)) expected_raw = [ ' deny capability chgrp, # example comment', '', ] expected_clean = [ ' deny capability chgrp, # example comment', '', ] self.assertEqual(self.ruleset.delete_duplicates(inc), 2) self.assertEqual(expected_raw, self.ruleset.get_raw(1)) self.assertEqual(expected_clean, self.ruleset.get_clean(1)) def test_delete_duplicates_none(self): expected_raw = [ ' capability chown,', ' allow capability sys_admin,', ' deny capability chgrp, # example comment', '', ] expected_clean = [ ' deny capability chgrp, # example comment', '', ' allow capability sys_admin,', ' capability chown,', '', ] self.assertEqual(self.ruleset.delete_duplicates(None), 0) self.assertEqual(expected_raw, self.ruleset.get_raw(1)) self.assertEqual(expected_clean, self.ruleset.get_clean(1)) def test_delete_duplicates_hasher(self): expected_raw = [ ' capability chown,', ' allow capability sys_admin,', ' deny capability chgrp, # example comment', '', ] expected_clean = [ ' deny capability chgrp, # example comment', '', ' allow capability sys_admin,', ' capability chown,', '', ] self.assertEqual(self.ruleset.delete_duplicates(hasher()), 0) self.assertEqual(expected_raw, self.ruleset.get_raw(1)) self.assertEqual(expected_clean, self.ruleset.get_clean(1)) def _check_test_delete_duplicates_in_profile(self, rules, expected_raw, expected_clean, expected_deleted): obj = CapabilityRuleset() for rule in rules: obj.add(CapabilityRule.parse(rule)) deleted = obj.delete_duplicates(None) self.assertEqual(expected_raw, obj.get_raw(1)) self.assertEqual(expected_clean, obj.get_clean(1)) self.assertEqual(deleted, expected_deleted) def test_delete_duplicates_in_profile_01(self): rules = [ 'audit capability chown,', 'audit capability,', 'capability dac_override,', ] expected_raw = [ ' audit capability,', '', ] expected_clean = [ ' audit capability,', '', ] expected_deleted = 2 self._check_test_delete_duplicates_in_profile(rules, expected_raw, expected_clean, expected_deleted) def test_delete_duplicates_in_profile_02(self): rules = [ 'audit capability chown,', 'audit capability,', 'audit capability dac_override,', 'capability ,', 'audit capability ,', ] expected_raw = [ ' audit capability,', '', ] expected_clean = [ ' audit capability,', '', ] expected_deleted = 4 self._check_test_delete_duplicates_in_profile(rules, expected_raw, expected_clean, expected_deleted) def test_delete_duplicates_in_profile_03(self): rules = [ 'audit capability chown,', 'capability dac_override,', 'deny capability dac_override,', 'capability dac_override,', 'audit capability chown,', 'deny capability chown,', 'audit deny capability chown,', 'capability,', 'audit capability,', ] expected_raw = [ ' deny capability dac_override,', ' audit deny capability chown,', ' audit capability,', '', ] expected_clean = [ ' audit deny capability chown,', ' deny capability dac_override,', '', ' audit capability,', '', ] expected_deleted = 6 self._check_test_delete_duplicates_in_profile(rules, expected_raw, expected_clean, expected_deleted) def test_delete_duplicates_in_profile_04(self): rules = [ 'audit capability chown,', 'deny capability chown,', ] expected_raw = [ ' audit capability chown,', ' deny capability chown,', '', ] expected_clean = [ ' deny capability chown,', '', ' audit capability chown,', '', ] expected_deleted = 0 self._check_test_delete_duplicates_in_profile(rules, expected_raw, expected_clean, expected_deleted) setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-mount_parse.py0000644000175000017500000000304313502024172017207 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import apparmor.aa as aa import unittest from common_test import AAParseTest, setup_regex_tests, setup_aa class BaseAAParseMountTest(AAParseTest): def setUp(self): self.parse_function = aa.parse_mount_rule class AAParseMountTest(BaseAAParseMountTest): tests = [ ('mount,', 'mount base keyword rule'), ('mount -o ro,', 'mount ro rule'), ('mount -o rw /dev/sdb1 -> /mnt/external,', 'mount rw with mount point'), ] class AAParseRemountTest(BaseAAParseMountTest): tests = [ ('remount,', 'remount base keyword rule'), ('remount -o ro,', 'remount ro rule'), ('remount -o ro /,', 'remount ro with mountpoint'), ] class AAParseUmountTest(BaseAAParseMountTest): tests = [ ('umount,', 'umount base keyword rule'), ('umount /mnt/external,', 'umount with mount point'), ('unmount,', 'unmount base keyword rule'), ('unmount /mnt/external,', 'unmount with mount point'), ] setup_aa(aa) if __name__ == '__main__': setup_regex_tests(AAParseMountTest) setup_regex_tests(AAParseRemountTest) setup_regex_tests(AAParseUmountTest) unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-ptrace.py0000644000175000017500000007350313502024172016141 0ustar jjjj#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import unittest from collections import namedtuple from common_test import AATest, setup_all_loops from apparmor.rule.ptrace import PtraceRule, PtraceRuleset from apparmor.rule import BaseRule from apparmor.common import AppArmorException, AppArmorBug from apparmor.logparser import ReadLog from apparmor.translations import init_translation _ = init_translation() exp = namedtuple('exp', ['audit', 'allow_keyword', 'deny', 'comment', 'access', 'all_access', 'peer', 'all_peers']) # # --- tests for single PtraceRule --- # class PtraceTest(AATest): def _compare_obj(self, obj, expected): self.assertEqual(expected.allow_keyword, obj.allow_keyword) self.assertEqual(expected.audit, obj.audit) self.assertEqual(expected.access, obj.access) if obj.peer: self.assertEqual(expected.peer, obj.peer.regex) else: self.assertEqual(expected.peer, obj.peer) self.assertEqual(expected.all_access, obj.all_access) self.assertEqual(expected.all_peers, obj.all_peers) self.assertEqual(expected.deny, obj.deny) self.assertEqual(expected.comment, obj.comment) class PtraceTestParse(PtraceTest): tests = [ # PtraceRule object audit allow deny comment access all? peer all? ('ptrace,' , exp(False, False, False, '', None , True , None, True )), # ('ptrace (),' , exp(False, False, False, '', None , True , None, True )), # XXX also broken in SignalRule? ('ptrace read,' , exp(False, False, False, '', {'read'}, False, None, True )), ('ptrace (read, tracedby),' , exp(False, False, False, '', {'read', 'tracedby'}, False, None, True )), ('ptrace read,' , exp(False, False, False, '', {'read'}, False, None, True )), ('deny ptrace read, # cmt' , exp(False, False, True , ' # cmt', {'read'}, False, None, True )), ('audit allow ptrace,' , exp(True , True , False, '', None , True , None, True )), ('ptrace peer=unconfined,' , exp(False, False, False, '', None , True , 'unconfined', False )), ('ptrace peer="unconfined",' , exp(False, False, False, '', None , True , 'unconfined', False )), ('ptrace read,' , exp(False, False, False, '', {'read'}, False, None, True )), ('ptrace peer=/foo,' , exp(False, False, False, '', None , True , '/foo', False )), ('ptrace r peer=/foo,' , exp(False, False, False, '', {'r'}, False, '/foo', False )), ('ptrace r peer="/foo bar",' , exp(False, False, False, '', {'r'}, False, '/foo bar', False )), ] def _run_test(self, rawrule, expected): self.assertTrue(PtraceRule.match(rawrule)) obj = PtraceRule.parse(rawrule) self.assertEqual(rawrule.strip(), obj.raw_rule) self._compare_obj(obj, expected) class PtraceTestParseInvalid(PtraceTest): tests = [ ('ptrace foo,' , AppArmorException), ('ptrace foo bar,' , AppArmorException), ('ptrace foo int,' , AppArmorException), ('ptrace read bar,' , AppArmorException), ('ptrace read tracedby,' , AppArmorException), ('ptrace peer=,' , AppArmorException), ] def _run_test(self, rawrule, expected): self.assertTrue(PtraceRule.match(rawrule)) # the above invalid rules still match the main regex! with self.assertRaises(expected): PtraceRule.parse(rawrule) class PtraceTestParseFromLog(PtraceTest): def test_ptrace_from_log(self): parser = ReadLog('', '', '', '') event = 'type=AVC msg=audit(1409700683.304:547661): apparmor="DENIED" operation="ptrace" profile="/home/ubuntu/bzr/apparmor/tests/regression/apparmor/ptrace" pid=22465 comm="ptrace" requested_mask="tracedby" denied_mask="tracedby" peer="/home/ubuntu/bzr/apparmor/tests/regression/apparmor/ptrace"' parsed_event = parser.parse_event(event) self.assertEqual(parsed_event, { 'request_mask': 'tracedby', 'denied_mask': 'tracedby', 'error_code': 0, 'magic_token': 0, 'parent': 0, 'profile': '/home/ubuntu/bzr/apparmor/tests/regression/apparmor/ptrace', 'peer': '/home/ubuntu/bzr/apparmor/tests/regression/apparmor/ptrace', 'operation': 'ptrace', 'resource': None, 'info': None, 'aamode': 'REJECTING', 'time': 1409700683, 'active_hat': None, 'pid': 22465, 'task': 0, 'attr': None, 'name2': None, 'name': None, 'family': None, 'protocol': None, 'sock_type': None, }) obj = PtraceRule(parsed_event['denied_mask'], parsed_event['peer'], log_event=parsed_event) # audit allow deny comment access all? peer all? expected = exp(False, False, False, '', {'tracedby'}, False, '/home/ubuntu/bzr/apparmor/tests/regression/apparmor/ptrace', False) self._compare_obj(obj, expected) self.assertEqual(obj.get_raw(1), ' ptrace tracedby peer=/home/ubuntu/bzr/apparmor/tests/regression/apparmor/ptrace,') class PtraceFromInit(PtraceTest): tests = [ # PtraceRule object audit allow deny comment access all? peer all? (PtraceRule('r', 'unconfined', deny=True) , exp(False, False, True , '' , {'r'}, False, 'unconfined', False)), (PtraceRule(('r', 'read'), '/bin/foo') , exp(False, False, False, '' , {'r', 'read'},False, '/bin/foo', False)), (PtraceRule(PtraceRule.ALL, '/bin/foo') , exp(False, False, False, '' , None, True, '/bin/foo', False )), (PtraceRule('rw', '/bin/foo') , exp(False, False, False, '' , {'rw'}, False, '/bin/foo', False )), (PtraceRule('rw', PtraceRule.ALL) , exp(False, False, False, '' , {'rw'}, False, None, True )), (PtraceRule(PtraceRule.ALL, PtraceRule.ALL) , exp(False, False, False, '' , None , True, None, True )), ] def _run_test(self, obj, expected): self._compare_obj(obj, expected) class InvalidPtraceInit(AATest): tests = [ # init params expected exception (['' , '/foo' ] , AppArmorBug), # empty access (['read', '' ] , AppArmorBug), # empty peer ([' ', '/foo' ] , AppArmorBug), # whitespace access (['read', ' ' ] , AppArmorBug), # whitespace peer (['xyxy', '/foo' ] , AppArmorException), # invalid access # XXX is 'invalid peer' possible at all? ([dict(), '/foo' ] , AppArmorBug), # wrong type for access ([None , '/foo' ] , AppArmorBug), # wrong type for access (['read', dict() ] , AppArmorBug), # wrong type for peer (['read', None ] , AppArmorBug), # wrong type for peer ] def _run_test(self, params, expected): with self.assertRaises(expected): PtraceRule(params[0], params[1]) def test_missing_params_1(self): with self.assertRaises(TypeError): PtraceRule() def test_missing_params_2(self): with self.assertRaises(TypeError): PtraceRule('r') class InvalidPtraceTest(AATest): def _check_invalid_rawrule(self, rawrule): obj = None self.assertFalse(PtraceRule.match(rawrule)) with self.assertRaises(AppArmorException): obj = PtraceRule(PtraceRule.parse(rawrule)) self.assertIsNone(obj, 'PtraceRule handed back an object unexpectedly') def test_invalid_ptrace_missing_comma(self): self._check_invalid_rawrule('ptrace') # missing comma def test_invalid_non_PtraceRule(self): self._check_invalid_rawrule('dbus,') # not a ptrace rule def test_empty_data_1(self): obj = PtraceRule('read', '/foo') obj.access = '' # no access set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) def test_empty_data_2(self): obj = PtraceRule('read', '/foo') obj.peer = '' # no ptrace set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) class WritePtraceTestAATest(AATest): def _run_test(self, rawrule, expected): self.assertTrue(PtraceRule.match(rawrule)) obj = PtraceRule.parse(rawrule) clean = obj.get_clean() raw = obj.get_raw() self.assertEqual(expected.strip(), clean, 'unexpected clean rule') self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule') tests = [ # raw rule clean rule ('ptrace,' , 'ptrace,'), (' ptrace , # foo ' , 'ptrace, # foo'), (' audit ptrace read,' , 'audit ptrace read,'), (' audit ptrace (read ),' , 'audit ptrace read,'), (' audit ptrace (read , tracedby ),' , 'audit ptrace (read tracedby),'), (' deny ptrace read ,# foo bar' , 'deny ptrace read, # foo bar'), (' deny ptrace ( read ), ' , 'deny ptrace read,'), (' allow ptrace ,# foo bar' , 'allow ptrace, # foo bar'), ('ptrace,' , 'ptrace,'), ('ptrace (trace),' , 'ptrace trace,'), ('ptrace (tracedby),' , 'ptrace tracedby,'), ('ptrace (read),' , 'ptrace read,'), ('ptrace (readby),' , 'ptrace readby,'), ('ptrace (trace read),' , 'ptrace (read trace),'), ('ptrace (read tracedby),' , 'ptrace (read tracedby),'), ('ptrace r,' , 'ptrace r,'), ('ptrace w,' , 'ptrace w,'), ('ptrace rw,' , 'ptrace rw,'), ('ptrace read,' , 'ptrace read,'), ('ptrace (tracedby),' , 'ptrace tracedby,'), ('ptrace w,' , 'ptrace w,'), ('ptrace read peer=foo,' , 'ptrace read peer=foo,'), ('ptrace tracedby peer=foo,' , 'ptrace tracedby peer=foo,'), ('ptrace (read tracedby) peer=/usr/bin/bar,' , 'ptrace (read tracedby) peer=/usr/bin/bar,'), ('ptrace (trace read) peer=/usr/bin/bar,' , 'ptrace (read trace) peer=/usr/bin/bar,'), ('ptrace wr peer=/sbin/baz,' , 'ptrace wr peer=/sbin/baz,'), ] def test_write_manually(self): obj = PtraceRule('read', '/foo', allow_keyword=True) expected = ' allow ptrace read peer=/foo,' self.assertEqual(expected, obj.get_clean(2), 'unexpected clean rule') self.assertEqual(expected, obj.get_raw(2), 'unexpected raw rule') class PtraceCoveredTest(AATest): def _run_test(self, param, expected): obj = PtraceRule.parse(self.rule) check_obj = PtraceRule.parse(param) self.assertTrue(PtraceRule.match(param)) self.assertEqual(obj.is_equal(check_obj), expected[0], 'Mismatch in is_equal, expected %s' % expected[0]) self.assertEqual(obj.is_equal(check_obj, True), expected[1], 'Mismatch in is_equal/strict, expected %s' % expected[1]) self.assertEqual(obj.is_covered(check_obj), expected[2], 'Mismatch in is_covered, expected %s' % expected[2]) self.assertEqual(obj.is_covered(check_obj, True, True), expected[3], 'Mismatch in is_covered/exact, expected %s' % expected[3]) class PtraceCoveredTest_01(PtraceCoveredTest): rule = 'ptrace read,' tests = [ # rule equal strict equal covered covered exact ('ptrace,' , [ False , False , False , False ]), ('ptrace read,' , [ True , True , True , True ]), ('ptrace read peer=unconfined,' , [ False , False , True , True ]), ('ptrace read, # comment' , [ True , False , True , True ]), ('allow ptrace read,' , [ True , False , True , True ]), ('ptrace read,' , [ True , False , True , True ]), ('audit ptrace read,' , [ False , False , False , False ]), ('audit ptrace,' , [ False , False , False , False ]), ('ptrace tracedby,' , [ False , False , False , False ]), ('audit deny ptrace read,' , [ False , False , False , False ]), ('deny ptrace read,' , [ False , False , False , False ]), ] class PtraceCoveredTest_02(PtraceCoveredTest): rule = 'audit ptrace read,' tests = [ # rule equal strict equal covered covered exact ( 'ptrace read,' , [ False , False , True , False ]), ('audit ptrace read,' , [ True , True , True , True ]), ( 'ptrace,' , [ False , False , False , False ]), ('audit ptrace,' , [ False , False , False , False ]), ('ptrace tracedby,' , [ False , False , False , False ]), ] class PtraceCoveredTest_03(PtraceCoveredTest): rule = 'ptrace,' tests = [ # rule equal strict equal covered covered exact ( 'ptrace,' , [ True , True , True , True ]), ('allow ptrace,' , [ True , False , True , True ]), ( 'ptrace read,' , [ False , False , True , True ]), ( 'ptrace w,' , [ False , False , True , True ]), ('audit ptrace,' , [ False , False , False , False ]), ('deny ptrace,' , [ False , False , False , False ]), ] class PtraceCoveredTest_04(PtraceCoveredTest): rule = 'deny ptrace read,' tests = [ # rule equal strict equal covered covered exact ( 'deny ptrace read,' , [ True , True , True , True ]), ('audit deny ptrace read,' , [ False , False , False , False ]), ( 'ptrace read,' , [ False , False , False , False ]), # XXX should covered be true here? ( 'deny ptrace tracedby,' , [ False , False , False , False ]), ( 'deny ptrace,' , [ False , False , False , False ]), ] class PtraceCoveredTest_05(PtraceCoveredTest): rule = 'ptrace read peer=unconfined,' tests = [ # rule equal strict equal covered covered exact ('ptrace,' , [ False , False , False , False ]), ('ptrace read,' , [ False , False , False , False ]), ('ptrace read peer=unconfined,' , [ True , True , True , True ]), ('ptrace peer=unconfined,' , [ False , False , False , False ]), ('ptrace read, # comment' , [ False , False , False , False ]), ('allow ptrace read,' , [ False , False , False , False ]), ('allow ptrace read peer=unconfined,' , [ True , False , True , True ]), ('allow ptrace read peer=/foo/bar,' , [ False , False , False , False ]), ('allow ptrace read peer=/**,' , [ False , False , False , False ]), ('allow ptrace read peer=**,' , [ False , False , False , False ]), ('ptrace read,' , [ False , False , False , False ]), ('ptrace read peer=unconfined,' , [ True , False , True , True ]), ('audit ptrace read peer=unconfined,' , [ False , False , False , False ]), ('audit ptrace,' , [ False , False , False , False ]), ('ptrace tracedby,' , [ False , False , False , False ]), ('audit deny ptrace read,' , [ False , False , False , False ]), ('deny ptrace read,' , [ False , False , False , False ]), ] class PtraceCoveredTest_06(PtraceCoveredTest): rule = 'ptrace read peer=/foo/bar,' tests = [ # rule equal strict equal covered covered exact ('ptrace,' , [ False , False , False , False ]), ('ptrace read,' , [ False , False , False , False ]), ('ptrace read peer=/foo/bar,' , [ True , True , True , True ]), ('ptrace read peer=/foo/*,' , [ False , False , False , False ]), ('ptrace read peer=/**,' , [ False , False , False , False ]), ('ptrace read peer=/what/*,' , [ False , False , False , False ]), ('ptrace peer=/foo/bar,' , [ False , False , False , False ]), ('ptrace read, # comment' , [ False , False , False , False ]), ('allow ptrace read,' , [ False , False , False , False ]), ('allow ptrace read peer=/foo/bar,' , [ True , False , True , True ]), ('ptrace read,' , [ False , False , False , False ]), ('ptrace read peer=/foo/bar,' , [ True , False , True , True ]), ('ptrace read peer=/what/ever,' , [ False , False , False , False ]), ('audit ptrace read peer=/foo/bar,' , [ False , False , False , False ]), ('audit ptrace,' , [ False , False , False , False ]), ('ptrace tracedby,' , [ False , False , False , False ]), ('audit deny ptrace read,' , [ False , False , False , False ]), ('deny ptrace read,' , [ False , False , False , False ]), ] class PtraceCoveredTest_07(PtraceCoveredTest): rule = 'ptrace read peer=**,' tests = [ # rule equal strict equal covered covered exact ('ptrace,' , [ False , False , False , False ]), ('ptrace read,' , [ False , False , False , False ]), ('ptrace read peer=/foo/bar,' , [ False , False , True , True ]), ('ptrace read peer=/foo/*,' , [ False , False , True , True ]), ('ptrace read peer=/**,' , [ False , False , True , True ]), ('ptrace read peer=/what/*,' , [ False , False , True , True ]), ('ptrace peer=/foo/bar,' , [ False , False , False , False ]), ('ptrace read, # comment' , [ False , False , False , False ]), ('allow ptrace read,' , [ False , False , False , False ]), ('allow ptrace read peer=/foo/bar,' , [ False , False , True , True ]), ('ptrace read,' , [ False , False , False , False ]), ('ptrace read peer=/foo/bar,' , [ False , False , True , True ]), ('ptrace read peer=/what/ever,' , [ False , False , True , True ]), ('audit ptrace read peer=/foo/bar,' , [ False , False , False , False ]), ('audit ptrace,' , [ False , False , False , False ]), ('ptrace tracedby,' , [ False , False , False , False ]), ('audit deny ptrace read,' , [ False , False , False , False ]), ('deny ptrace read,' , [ False , False , False , False ]), ] class PtraceCoveredTest_08(PtraceCoveredTest): rule = 'ptrace (trace, tracedby) peer=/foo/*,' tests = [ # rule equal strict equal covered covered exact ('ptrace,' , [ False , False , False , False ]), ('ptrace trace,' , [ False , False , False , False ]), ('ptrace (tracedby, trace),' , [ False , False , False , False ]), ('ptrace trace peer=/foo/bar,' , [ False , False , True , True ]), ('ptrace (tracedby trace) peer=/foo/bar,',[ False , False , True , True ]), ('ptrace (tracedby, trace) peer=/foo/*,', [ True , False , True , True ]), ('ptrace tracedby peer=/foo/bar,' , [ False , False , True , True ]), ('ptrace trace peer=/foo/*,' , [ False , False , True , True ]), ('ptrace trace peer=/**,' , [ False , False , False , False ]), ('ptrace trace peer=/what/*,' , [ False , False , False , False ]), ('ptrace peer=/foo/bar,' , [ False , False , False , False ]), ('ptrace trace, # comment' , [ False , False , False , False ]), ('allow ptrace trace,' , [ False , False , False , False ]), ('allow ptrace trace peer=/foo/bar,' , [ False , False , True , True ]), ('ptrace trace,' , [ False , False , False , False ]), ('ptrace trace peer=/foo/bar,' , [ False , False , True , True ]), ('ptrace trace peer=/what/ever,' , [ False , False , False , False ]), ('audit ptrace trace peer=/foo/bar,' , [ False , False , False , False ]), ('audit ptrace,' , [ False , False , False , False ]), ('ptrace tracedby,' , [ False , False , False , False ]), ('audit deny ptrace trace,' , [ False , False , False , False ]), ('deny ptrace trace,' , [ False , False , False , False ]), ] class PtraceCoveredTest_Invalid(AATest): def test_borked_obj_is_covered_1(self): obj = PtraceRule.parse('ptrace read peer=/foo,') testobj = PtraceRule('read', '/foo') testobj.access = '' with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_borked_obj_is_covered_2(self): obj = PtraceRule.parse('ptrace read peer=/foo,') testobj = PtraceRule('read', '/foo') testobj.peer = '' with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_invalid_is_covered(self): obj = PtraceRule.parse('ptrace read,') testobj = BaseRule() # different type with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_invalid_is_equal(self): obj = PtraceRule.parse('ptrace read,') testobj = BaseRule() # different type with self.assertRaises(AppArmorBug): obj.is_equal(testobj) class PtraceLogprofHeaderTest(AATest): tests = [ ('ptrace,', [ _('Access mode'), _('ALL'), _('Peer'), _('ALL'), ]), ('ptrace read,', [ _('Access mode'), 'read', _('Peer'), _('ALL'), ]), ('deny ptrace,', [_('Qualifier'), 'deny', _('Access mode'), _('ALL'), _('Peer'), _('ALL'), ]), ('allow ptrace read,', [_('Qualifier'), 'allow', _('Access mode'), 'read', _('Peer'), _('ALL'), ]), ('audit ptrace read,', [_('Qualifier'), 'audit', _('Access mode'), 'read', _('Peer'), _('ALL'), ]), ('audit deny ptrace read,', [_('Qualifier'), 'audit deny', _('Access mode'), 'read', _('Peer'), _('ALL'), ]), ('ptrace (read, tracedby) peer=/foo,', [ _('Access mode'), 'read tracedby', _('Peer'), '/foo', ]), ] def _run_test(self, params, expected): obj = PtraceRule._parse(params) self.assertEqual(obj.logprof_header(), expected) ## --- tests for PtraceRuleset --- # class PtraceRulesTest(AATest): def test_empty_ruleset(self): ruleset = PtraceRuleset() ruleset_2 = PtraceRuleset() self.assertEqual([], ruleset.get_raw(2)) self.assertEqual([], ruleset.get_clean(2)) self.assertEqual([], ruleset_2.get_raw(2)) self.assertEqual([], ruleset_2.get_clean(2)) def test_ruleset_1(self): ruleset = PtraceRuleset() rules = [ 'ptrace peer=/foo,', 'ptrace read,', ] expected_raw = [ 'ptrace peer=/foo,', 'ptrace read,', '', ] expected_clean = [ 'ptrace peer=/foo,', 'ptrace read,', '', ] for rule in rules: ruleset.add(PtraceRule.parse(rule)) self.assertEqual(expected_raw, ruleset.get_raw()) self.assertEqual(expected_clean, ruleset.get_clean()) def test_ruleset_2(self): ruleset = PtraceRuleset() rules = [ 'ptrace read peer=/foo,', 'allow ptrace read,', 'deny ptrace peer=/bar, # example comment', ] expected_raw = [ ' ptrace read peer=/foo,', ' allow ptrace read,', ' deny ptrace peer=/bar, # example comment', '', ] expected_clean = [ ' deny ptrace peer=/bar, # example comment', '', ' allow ptrace read,', ' ptrace read peer=/foo,', '', ] for rule in rules: ruleset.add(PtraceRule.parse(rule)) self.assertEqual(expected_raw, ruleset.get_raw(1)) self.assertEqual(expected_clean, ruleset.get_clean(1)) class PtraceGlobTestAATest(AATest): def setUp(self): self.maxDiff = None self.ruleset = PtraceRuleset() def test_glob_1(self): self.assertEqual(self.ruleset.get_glob('ptrace read,'), 'ptrace,') # not supported or used yet # def test_glob_2(self): # self.assertEqual(self.ruleset.get_glob('ptrace read raw,'), 'ptrace read,') def test_glob_ext(self): with self.assertRaises(NotImplementedError): # get_glob_ext is not available for ptrace rules self.ruleset.get_glob_ext('ptrace read peer=/foo,') #class PtraceDeleteTestAATest(AATest): # pass setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/common_test.py0000755000175000017500000001055213502024172016233 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import unittest import inspect import os import shutil import sys import tempfile #def test_readkey(self): # print("Please press the Y button on the keyboard.") # self.assertEqual(apparmor.common.readkey().lower(), 'y', 'Error reading key from shell!') class AATest(unittest.TestCase): def setUp(self): self.maxDiff = None self.AASetup() def AASetup(self): '''override this function if a test needs additional setup steps (instead of overriding setUp())''' pass def tearDown(self): if self.tmpdir and os.path.exists(self.tmpdir): shutil.rmtree(self.tmpdir) self.AATeardown() def AATeardown(self): '''override this function if a test needs additional teardown steps (instead of overriding tearDown())''' pass def createTmpdir(self): self.tmpdir = tempfile.mkdtemp(prefix='aa-test-') def writeTmpfile(self, file, contents): if not self.tmpdir: self.createTmpdir() return write_file(self.tmpdir, file, contents) tests = [] tmpdir = None class AAParseTest(unittest.TestCase): parse_function = None def _test_parse_rule(self, rule): self.assertIsNot(self.parse_function, 'Test class did not set a parse_function') parsed = self.parse_function(rule) self.assertEqual(rule, parsed.serialize(), 'parse object %s returned "%s", expected "%s"' \ %(self.parse_function.__doc__, parsed.serialize(), rule)) def setup_all_loops(module_name): '''call setup_tests_loop() for each class in module_name''' for name, obj in inspect.getmembers(sys.modules[module_name]): if inspect.isclass(obj): if issubclass(obj, unittest.TestCase): setup_tests_loop(obj) def setup_tests_loop(test_class): '''Create tests in test_class using test_class.tests and self._run_test() test_class.tests should be tuples of (test_data, expected_results) test_data and expected_results can be of any type as long as test_class._run_test() know how to handle them. A typical definition for _run_test() is: def test_class._run_test(self, test_data, expected) ''' for (i, (test_data, expected)) in enumerate(test_class.tests): def stub_test(self, test_data=test_data, expected=expected): self._run_test(test_data, expected) stub_test.__doc__ = "test '%s'" % str(test_data) setattr(test_class, 'test_%d' % (i), stub_test) def setup_regex_tests(test_class): '''Create tests in test_class using test_class.tests and AAParseTest._test_parse_rule() test_class.tests should be tuples of (line, description) ''' for (i, (line, desc)) in enumerate(test_class.tests): def stub_test(self, line=line): self._test_parse_rule(line) stub_test.__doc__ = "test '%s': %s" % (line, desc) setattr(test_class, 'test_%d' % (i), stub_test) def setup_aa(aa): confdir = os.getenv('__AA_CONFDIR') try: if confdir: aa.init_aa(confdir=confdir) else: aa.init_aa() except AttributeError: # apparmor.aa module versions <= 2.11 do not have the init_aa() method pass def write_file(directory, file, contents): '''construct path, write contents to it, and return the constructed path''' path = os.path.join(directory, file) with open(path, 'w+') as f: f.write(contents) return path def read_file(path): '''read and return file contents''' with open(path, 'r') as f: return f.read() if __name__ == "__main__": #import sys;sys.argv = ['', 'Test.test_RegexParser'] unittest.main() apparmor-2.13.3/utils/test/test-pivot_root_parse.py0000644000175000017500000000177013502024172020256 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import apparmor.aa as aa import unittest from common_test import AAParseTest, setup_regex_tests, setup_aa class AAParsePivotRootTest(AAParseTest): def setUp(self): self.parse_function = aa.parse_pivot_root_rule tests = [ ('pivot_root,', 'pivot_root base keyword'), ('pivot_root /old,', 'pivot_root oldroot rule'), ('pivot_root /old /new,', 'pivot_root old and new root rule'), ('pivot_root /old /new -> /usr/bin/child,', 'pivot_root child rule'), ] setup_aa(aa) if __name__ == '__main__': setup_regex_tests(AAParsePivotRootTest) unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-baserule.py0000644000175000017500000000543013502024172016457 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import unittest from common_test import AATest, setup_all_loops from apparmor.common import AppArmorBug from apparmor.rule import BaseRule, parse_modifiers import apparmor.severity as severity import re class TestBaserule(AATest): def test_abstract__parse(self): with self.assertRaises(NotImplementedError): BaseRule._parse('foo') def test_abstract__parse_2(self): with self.assertRaises(NotImplementedError): BaseRule.parse('foo') def test_abstract__match(self): with self.assertRaises(NotImplementedError): BaseRule._match('foo') def test_abstract__match2(self): with self.assertRaises(NotImplementedError): BaseRule.match('foo') def test_abstract_get_clean(self): obj = BaseRule() with self.assertRaises(NotImplementedError): obj.get_clean() def test_is_equal_localvars(self): obj = BaseRule() with self.assertRaises(NotImplementedError): obj.is_equal_localvars(BaseRule(), False) def test_is_covered_localvars(self): obj = BaseRule() with self.assertRaises(NotImplementedError): obj.is_covered_localvars(None) def test_parse_modifiers_invalid(self): regex = re.compile('^\s*(?Paudit\s+)?(?Pallow\s+|deny\s+|invalid\s+)?') matches = regex.search('audit invalid ') with self.assertRaises(AppArmorBug): parse_modifiers(matches) def test_default_severity(self): sev_db = severity.Severity('severity.db', 'unknown') obj = BaseRule() rank = obj.severity(sev_db) self.assertEqual(rank, sev_db.NOT_IMPLEMENTED) def test_logprof_header_localvars(self): obj = BaseRule() with self.assertRaises(NotImplementedError): obj.logprof_header_localvars() def test_edit_header_localvars(self): obj = BaseRule() with self.assertRaises(NotImplementedError): obj.edit_header() def test_validate_edit_localvars(self): obj = BaseRule() with self.assertRaises(NotImplementedError): obj.validate_edit('/foo') def test_store_edit_localvars(self): obj = BaseRule() with self.assertRaises(NotImplementedError): obj.store_edit('/foo') setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/logprof.conf0000644000175000017500000001017513502024172015647 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2004-2006 Novell/SUSE # Copyright (C) 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ [settings] profiledir = ../../profiles/apparmor.d inactive_profiledir = ../../profiles/apparmor/profiles/extra logfiles = /var/log/audit/audit.log /var/log/syslog /var/log/messages parser = ../../parser/apparmor_parser ldd = /usr/bin/ldd logger = /bin/logger /usr/bin/logger # customize how file ownership permissions are presented # 0 - off # 1 - default of what ever mode the log reported # 2 - force the new permissions to be user # 3 - force all perms on the rule to be user default_owner_prompt = 1 # custom directory locations to look for #includes # # each name should be a valid directory containing possible #include # candidate files under the profile dir which by default is /etc/apparmor.d. # # So an entry of my-includes will allow /etc/apparmor.d/my-includes to # be used by the yast UI and profiling tools as a source of #include # files. custom_includes = [repository] distro = ubuntu-intrepid url = http://apparmor.test.opensuse.org/backend/api preferred_user = ubuntu [qualifiers] # things will be painfully broken if bash has a profile /bin/bash = icnu /bin/ksh = icnu /bin/dash = icnu # these programs can't function if they're confined /bin/mount = u /etc/init.d/subdomain = u /sbin/cardmgr = u /sbin/subdomain_parser = u /usr/sbin/genprof = u /usr/sbin/logprof = u /usr/lib/YaST2/servers_non_y2/ag_genprof = u /usr/lib/YaST2/servers_non_y2/ag_logprof = u # these ones shouln't have their own profiles /bin/awk = icn /bin/cat = icn /bin/chmod = icn /bin/chown = icn /bin/cp = icn /bin/gawk = icn /bin/grep = icn /bin/gunzip = icn /bin/gzip = icn /bin/kill = icn /bin/ln = icn /bin/ls = icn /bin/mkdir = icn /bin/mv = icn /bin/readlink = icn /bin/rm = icn /bin/sed = icn /bin/touch = icn /sbin/killall5 = icn /usr/bin/find = icn /usr/bin/killall = icn /usr/bin/nice = icn /usr/bin/perl = icn /usr/bin/tr = icn [required_hats] ^.+/apache(|2|2-prefork)$ = DEFAULT_URI HANDLING_UNTRUSTED_INPUT ^.+/httpd(|2|2-prefork)$ = DEFAULT_URI HANDLING_UNTRUSTED_INPUT [defaulthat] ^.+/apache(|2|2-prefork)$ = DEFAULT_URI ^.+/httpd(|2|2-prefork)$ = DEFAULT_URI [globs] # /foo/bar/lib/libbaz.so -> /foo/bar/lib/lib* /lib/lib[^\/]+so[^\/]*$ = /lib/lib*so* # strip kernel version numbers from kernel module accesses ^/lib/modules/[^\/]+\/ = /lib/modules/*/ # strip pid numbers from /proc accesses ^/proc/\d+/ = /proc/*/ # if it looks like a home directory, glob out the username ^/home/[^\/]+ = /home/* # if they use any perl modules, grant access to all ^/usr/lib/perl5/.+$ = /usr/lib/perl5/** ^/usr/lib/[^\/]+/perl5?/.+$ = /usr/lib/@{multiarch}/perl{,5}/** # locale foo ^/usr/lib/locale/.+$ = /usr/lib/locale/** ^/usr/share/locale/.+$ = /usr/share/locale/** # timezone fun ^/usr/share/zoneinfo/.+$ = /usr/share/zoneinfo/** # /foobar/fonts/baz -> /foobar/fonts/** /fonts/.+$ = /fonts/** # turn /foo/bar/baz.8907234 into /foo/bar/baz.* # BUGBUG - this one looked weird because it would suggest a glob for # BUGBUG - libfoo.so.5.6.0 that looks like libfoo.so.5.6.* # \.\d+$ = .* # some various /etc/security poo -- dunno about these ones... ^/etc/security/_[^\/]+$ = /etc/security/* ^/lib/security/pam_filter/[^\/]+$ = /lib/security/pam_filter/* ^/lib/security/pam_[^\/]+\.so$ = /lib/security/pam_*.so ^/etc/pam.d/[^\/]+$ = /etc/pam.d/* ^/etc/profile.d/[^\/]+\.sh$ = /etc/profile.d/*.sh apparmor-2.13.3/utils/test/test-example.py0000644000175000017500000000251413502024172016310 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import unittest from common_test import AATest, setup_all_loops class TestFoo(AATest): tests = [ (0, 0 ), (42, 42), ] def _run_test(self, params, expected): self.assertEqual(params, expected) class TestBar(AATest): tests = [ ('a', 'foo'), ('b', 'bar'), ('c', 'baz'), ] def _run_test(self, params, expected): self.assertNotEqual(params, expected) def testAdditionalBarTest(self): self.assertEqual(1, 1) class TestBaz(AATest): def AASetup(self): # called by setUp() - use AASetup() to avoid the need for using super(...) pass def AATeardown(self): # called by tearDown() - use AATeardown() to avoid the need for using super(...) pass def test_Baz_only_one_test(self): self.assertEqual("baz", "baz") setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-severity.py0000755000175000017500000001505113502024172016532 0ustar jjjj#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2014 Canonical, Ltd. # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import unittest from common_test import AATest, setup_all_loops import apparmor.severity as severity from apparmor.common import AppArmorException class SeverityBaseTest(AATest): def AASetup(self): self.sev_db = severity.Severity('severity.db', 'unknown') def _capability_severity_test(self, cap, expected_rank): rank = self.sev_db.rank_capability(cap) self.assertEqual(rank, expected_rank, 'expected rank %s, got %s' % (expected_rank, rank)) def _simple_severity_w_perm(self, path, perm, expected_rank): rank = self.sev_db.rank_path(path, perm) self.assertEqual(rank, expected_rank, 'expected rank %s, got %s' % (expected_rank, rank)) class SeverityTest(SeverityBaseTest): tests = [ (['/usr/bin/whatis', 'x' ], 5), (['/etc', 'x' ], 'unknown'), (['/dev/doublehit', 'x' ], 0), (['/dev/doublehit', 'rx' ], 4), (['/dev/doublehit', 'rwx' ], 8), (['/dev/tty10', 'rwx' ], 9), (['/var/adm/foo/**', 'rx' ], 3), (['/etc/apparmor/**', 'r' ], 6), (['/etc/**', 'r' ], 'unknown'), (['/usr/foo@bar', 'r' ], 'unknown'), ## filename containing @ (['/home/foo@bar', 'rw' ], 6), ## filename containing @ ] def _run_test(self, params, expected): self._simple_severity_w_perm(params[0], params[1], expected) ## filename containing @ def test_invalid_rank(self): with self.assertRaises(AppArmorException): self._simple_severity_w_perm('unexpected_unput', 'rw', 6) class SeverityTestCap(SeverityBaseTest): tests = [ ('KILL', 8), ('SETPCAP', 9), ('setpcap', 9), ('UNKNOWN', 'unknown'), ('K*', 'unknown'), ('__ALL__', 10), ] def _run_test(self, params, expected): self._capability_severity_test(params, expected) rank = self.sev_db.rank_capability(params) self.assertEqual(rank, expected, 'expected rank %s, got %s' % (expected, rank)) class SeverityVarsTest(SeverityBaseTest): VARIABLE_DEFINITIONS = ''' @{HOME}=@{HOMEDIRS}/*/ /root/ @{HOMEDIRS}=/home/ # add another path to @{HOMEDIRS} @{HOMEDIRS}+=/storage/ @{multiarch}=*-linux-gnu* @{TFTP_DIR}=/var/tftp /srv/tftpboot @{PROC}=/proc/ @{pid}={[1-9],[1-9][0-9],[1-9][0-9][0-9],[1-9][0-9][0-9][0-9],[1-9][0-9][0-9][0-9][0-9],[1-9][0-9][0-9][0-9][0-9][0-9]} @{tid}=@{pid} @{pids}=@{pid} @{somepaths}=/home/foo/downloads @{HOMEDIRS}/foo/.ssh/ ''' def _init_tunables(self, content=''): if not content: content = self.VARIABLE_DEFINITIONS self.rules_file = self.writeTmpfile('tunables', content) self.sev_db.load_variables(self.rules_file) def AATeardown(self): self.sev_db.unload_variables() tests = [ (['@{PROC}/sys/vm/overcommit_memory', 'r'], 6), (['@{HOME}/sys/@{PROC}/overcommit_memory', 'r'], 4), (['/overco@{multiarch}mmit_memory', 'r'], 'unknown'), (['@{PROC}/sys/@{TFTP_DIR}/overcommit_memory', 'r'], 6), (['@{somepaths}/somefile', 'r'], 7), ] def _run_test(self, params, expected): self._init_tunables() self._simple_severity_w_perm(params[0], params[1], expected) def test_include(self): self._init_tunables('#include ') # including non-existing files doesn't raise an exception self.assertTrue(True) # this test only makes sure that loading the tunables file works def test_invalid_variable_add(self): with self.assertRaises(AppArmorException): self._init_tunables('@{invalid} += /home/') def test_invalid_variable_double_definition(self): with self.assertRaises(AppArmorException): self._init_tunables('@{foo} = /home/\n@{foo} = /root/') class SeverityDBTest(AATest): def _test_db(self, contents): self.db_file = self.writeTmpfile('severity.db', contents) self.sev_db = severity.Severity(self.db_file) return self.sev_db tests = [ ("CAP_LEASE 18\n" , AppArmorException), # out of range ("CAP_LEASE -1\n" , AppArmorException), # out of range ("/etc/passwd* 0 4\n" , AppArmorException), # insufficient vals ("/etc/passwd* 0 4 5 6\n" , AppArmorException), # too many vals ("/etc/passwd* -2 4 6\n" , AppArmorException), # out of range ("/etc/passwd* 12 4 6\n" , AppArmorException), # out of range ("/etc/passwd* 2 -4 6\n" , AppArmorException), # out of range ("/etc/passwd 2 14 6\n" , AppArmorException), # out of range ("/etc/passwd 2 4 -12\n" , AppArmorException), # out of range ("/etc/passwd 2 4 4294967297\n" , AppArmorException), # out of range ("garbage line\n" , AppArmorException), ] def _run_test(self, params, expected): with self.assertRaises(expected): self._test_db(params) def test_simple_db(self): self._test_db(''' CAP_LEASE 8 /etc/passwd* 4 8 0 ''') def test_cap_val_max_range(self): self._test_db("CAP_LEASE 10\n") def test_cap_val_min_range(self): self._test_db("CAP_LEASE 0\n") def test_invalid_db(self): self.assertRaises(AppArmorException, severity.Severity, 'severity_broken.db') def test_nonexistent_db(self): self.assertRaises(IOError, severity.Severity, 'severity.db.does.not.exist') def test_no_arg_to_severity(self): with self.assertRaises(AppArmorException): severity.Severity() setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-aare.py0000644000175000017500000004577313502024172015603 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import unittest from common_test import AATest, setup_all_loops from copy import deepcopy import re from apparmor.common import convert_regexp, AppArmorBug, AppArmorException from apparmor.aare import AARE, convert_expression_to_aare class TestConvert_regexp(AATest): tests = [ ('/foo', '^/foo$'), ('/{foo,bar}', '^/(foo|bar)$'), # ('/\{foo,bar}', '^/\{foo,bar}$'), # XXX gets converted to ^/\(foo|bar)$ ('/fo[abc]', '^/fo[abc]$'), ('/foo bar', '^/foo bar$'), ('/x\y', '^/x\y$'), ('/x\[y', '^/x\[y$'), ('/x\\y', '^/x\\y$'), ('/fo?', '^/fo[^/\000]$'), ('/foo/*', '^/foo/(((?<=/)[^/\000]+)|((? # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import unittest from collections import namedtuple from common_test import AATest, setup_all_loops from apparmor.rule.dbus import DbusRule, DbusRuleset from apparmor.rule import BaseRule from apparmor.common import AppArmorException, AppArmorBug from apparmor.logparser import ReadLog from apparmor.translations import init_translation _ = init_translation() exp = namedtuple('exp', ['audit', 'allow_keyword', 'deny', 'comment', 'access', 'all_access', 'bus', 'all_buses', 'path', 'all_paths', 'name', 'all_names', 'interface', 'all_interfaces', 'member', 'all_members', 'peername', 'all_peernames', 'peerlabel', 'all_peerlabels']) # --- tests for single DbusRule --- # class DbusTest(AATest): def _compare_obj(self, obj, expected): self.assertEqual(obj.allow_keyword, expected.allow_keyword) self.assertEqual(obj.audit, expected.audit) self.assertEqual(obj.deny, expected.deny) self.assertEqual(obj.comment, expected.comment) self.assertEqual(obj.access, expected.access) self._assertEqual_aare(obj.bus, expected.bus) self._assertEqual_aare(obj.path, expected.path) self._assertEqual_aare(obj.name, expected.name) self._assertEqual_aare(obj.interface, expected.interface) self._assertEqual_aare(obj.member, expected.member) self._assertEqual_aare(obj.peername, expected.peername) self._assertEqual_aare(obj.peerlabel, expected.peerlabel) self.assertEqual(obj.all_access, expected.all_access) self.assertEqual(obj.all_buses, expected.all_buses) self.assertEqual(obj.all_paths, expected.all_paths) self.assertEqual(obj.all_names, expected.all_names) self.assertEqual(obj.all_interfaces, expected.all_interfaces) self.assertEqual(obj.all_members, expected.all_members) self.assertEqual(obj.all_peernames, expected.all_peernames) self.assertEqual(obj.all_peerlabels, expected.all_peerlabels) def _assertEqual_aare(self, obj, expected): if obj: self.assertEqual(obj.regex, expected) else: self.assertEqual(obj, expected) class DbusTestParse(DbusTest): tests = [ # DbusRule object audit allow deny comment access all? bus all? path all? name all? interface all? member all? peername all? peerlabel all? ('dbus,' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, None, True, None, True)), ('dbus ( ),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, None, True, None, True)), ('dbus ( , ),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, None, True, None, True)), ('dbus send,' , exp(False, False, False, '', {'send'}, False, None, True, None, True, None, True, None, True, None, True, None, True, None, True)), ('dbus (send, receive),' , exp(False, False, False, '', {'send', 'receive'}, False, None, True, None, True, None, True, None, True, None, True, None, True, None, True)), ('dbus send bus=session,' , exp(False, False, False, '', {'send'}, False, 'session', False, None, True, None, True, None, True, None, True, None, True, None, True)), ('deny dbus send bus="session", # cmt' , exp(False, False, True , ' # cmt', {'send'}, False, 'session', False, None, True, None, True, None, True, None, True, None, True, None, True)), ('audit allow dbus peer=(label=foo),' , exp(True , True , False, '', None , True , None, True, None, True, None, True, None, True, None, True, None, True, 'foo', False)), ('dbus bus=session path=/foo/bar,' , exp(False, False, False, '', None , True , 'session', False, '/foo/bar', False, None, True, None, True, None, True, None, True, None, True)), ('dbus send bus=(session),' , exp(False, False, False, '', {'send'}, False, 'session', False, None, True, None, True, None, True, None, True, None, True, None, True)), ('dbus name=(SomeService),' , exp(False, False, False, '', None, True, None, True, None, True, 'SomeService',False, None, True, None, True, None, True, None, True)), ('dbus send bus=session peer=(label="foo"),' , exp(False, False, False, '', {'send'}, False, 'session', False, None, True, None, True, None, True, None, True, None, True, 'foo', False)), ('dbus send bus = ( session ) , ' , exp(False, False, False, '', {'send'}, False, 'session', False, None, True, None, True, None, True, None, True, None, True, None, True)), ('dbus path=/foo,' , exp(False, False, False, '', None , True , None, True, '/foo', False, None, True, None, True, None, True, None, True, None, True)), ('dbus eavesdrop bus=session,' , exp(False, False, False, '', {'eavesdrop'}, False, 'session', False, None, True, None, True, None, True, None, True, None, True, None, True)), ('dbus peer=(name=foo label=bar),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, 'foo', False, 'bar', False)), ('dbus peer=( name = foo label = bar ),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, 'foo', False, 'bar', False)), ('dbus peer=( name = foo , label = bar ),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, 'foo', False, 'bar', False)), ('dbus peer=(, name = foo , label = bar ,),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, 'foo', False, 'bar', False)), ('dbus peer=( name = foo, label = bar ),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, 'foo,', False, 'bar', False)), # XXX peername includes the comma ('dbus peer=(label=bar name=foo),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, 'foo', False, 'bar', False)), ('dbus peer=( label = bar name = foo ),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, 'foo', False, 'bar', False)), ('dbus peer=(, label = bar , name = foo ,),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, 'foo', False, 'bar', False)), ('dbus peer=(, label = bar, name = foo ),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, 'foo', False, 'bar,', False)), # XXX peerlabel includes the comma ('dbus peer=( label = bar , name = foo ),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, 'foo', False, 'bar', False)), ('dbus peer=( label = "bar" name = "foo" ),' , exp(False, False, False, '', None , True , None, True, None, True, None, True, None, True, None, True, 'foo', False, 'bar', False)), ('dbus path=/foo/bar bus=session,' , exp(False, False, False, '', None , True , 'session', False, '/foo/bar', False, None, True, None, True, None, True, None, True, None, True)), ('dbus bus=system path=/foo/bar bus=session,' , exp(False, False, False, '', None , True , 'session', False, '/foo/bar', False, None, True, None, True, None, True, None, True, None, True)), # XXX bus= specified twice, last one wins ('dbus send peer=(label="foo") bus=session,' , exp(False, False, False, '', {'send'}, False, 'session', False, None, True, None, True, None, True, None, True, None, True, 'foo', False)), ('dbus bus=1 bus=2 bus=3 bus=4 bus=5 bus=6,' , exp(False, False, False, '', None , True , '6', False, None, True, None, True, None, True, None, True, None, True, None, True)), # XXX bus= specified multiple times, last one wins ] def _run_test(self, rawrule, expected): self.assertTrue(DbusRule.match(rawrule)) obj = DbusRule.parse(rawrule) self.assertEqual(rawrule.strip(), obj.raw_rule) self._compare_obj(obj, expected) class DbusTestParseInvalid(DbusTest): tests = [ ('dbus foo,' , AppArmorException), ('dbus foo bar,' , AppArmorException), ('dbus foo int,' , AppArmorException), ('dbus send bar,' , AppArmorException), ('dbus send receive,' , AppArmorException), ('dbus peer=,' , AppArmorException), ('dbus peer=(label=foo) path=,' , AppArmorException), ('dbus (invalid),' , AppArmorException), ('dbus peer=,' , AppArmorException), ('dbus bus=session bind bus=system,', AppArmorException), ('dbus bus=1 bus=2 bus=3 bus=4 bus=5 bus=6 bus=7,', AppArmorException), ] def _run_test(self, rawrule, expected): self.assertTrue(DbusRule.match(rawrule)) # the above invalid rules still match the main regex! with self.assertRaises(expected): DbusRule.parse(rawrule) class DbusTestParseFromLog(DbusTest): def test_dbus_from_log(self): parser = ReadLog('', '', '', '') event = 'type=USER_AVC msg=audit(1375323372.644:157): pid=363 uid=102 auid=4294967295 ses=4294967295 msg=\'apparmor="DENIED" operation="dbus_method_call" bus="system" name="org.freedesktop.DBus" path="/org/freedesktop/DBus" interface="org.freedesktop.DBus" member="Hello" mask="send" pid=2833 profile="/tmp/apparmor-2.8.0/tests/regression/apparmor/dbus_service" peer_profile="unconfined" exe="/bin/dbus-daemon" sauid=102 hostname=? addr=? terminal=?\'' parsed_event = parser.parse_event(event) self.assertEqual(parsed_event, { 'request_mask': None, 'denied_mask': 'send', 'error_code': 0, 'magic_token': 0, 'parent': 0, 'profile': '/tmp/apparmor-2.8.0/tests/regression/apparmor/dbus_service', 'bus': 'system', 'peer_profile': 'unconfined', 'operation': 'dbus_method_call', 'resource': None, 'info': None, 'aamode': 'REJECTING', 'time': 1375323372, 'active_hat': None, 'pid': 2833, 'task': 0, 'attr': None, 'name2': None, 'name': 'org.freedesktop.DBus', 'path': '/org/freedesktop/DBus', 'interface': 'org.freedesktop.DBus', 'member': 'Hello', 'family': None, 'protocol': None, 'sock_type': None, }) # XXX send rules must not contain name conditional, but the log event includes it - how should we handle this in logparser.py? # # access bus path name interface member peername peerlabel # obj = DbusRule(parsed_event['denied_mask'], parsed_event['bus'], parsed_event['path'], parsed_event['name'], parsed_event['interface'], parsed_event['member'], parsed_event['peer_profile'], DbusRule.ALL, log_event=parsed_event) # # DbusRule audit allow deny comment access all? bus all? path all? name all? interface all? member all? peername all? peerlabel all? # expected = exp( False, False, False, '', {'send'}, False, 'system', False, '/org/freedesktop/DBus', False, 'org.freedesktop.DBus', False, 'org.freedesktop.DBus', False, # 'Hello', False, 'unconfined', False, None, True) # self._compare_obj(obj, expected) # self.assertEqual(obj.get_raw(1), ' dbus send bus=system path=/org/freedesktop/DBus name=org.freedesktop.DBus member=Hello peer=(name=unconfined),') class DbusFromInit(DbusTest): tests = [ #DbusRule# access bus path name interface member peername peerlabel audit=, deny=, allow_keyword, comment=, log_event) (DbusRule( 'send' , 'session', DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL), #exp# audit allow deny comment access all? bus all? path all? name all? interface all? member all? peername all? peerlabel all? exp( False, False, False, '', {'send'}, False, 'session', False, None, True, None, True, None, True, None, True, None, True, None, True)), #DbusRule# access bus path name interface member peername peerlabel audit=, deny=, allow_keyword, comment=, log_event) (DbusRule(('send', 'receive'), 'session', DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL), #exp# audit allow deny comment access all? bus all? path all? name all? interface all? member all? peername all? peerlabel all? exp( False, False, False, '', {'send', 'receive'}, False, 'session', False, None, True, None, True, None, True, None, True, None, True, None, True)), #DbusRule# access bus path name interface member peername peerlabel audit=, deny=, allow_keyword, comment=, log_event) (DbusRule(DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, '/int/face', '/mem/ber', '/peer/name', '/peer/label'), #exp# audit allow deny comment access all? bus all? path all? name all? interface all? member all? peername all? peerlabel all? exp( False, False, False, '', None , True , None, True, None, True, None, True, '/int/face',False, '/mem/ber', False, '/peer/name', False, '/peer/label', False)), ] def _run_test(self, obj, expected): self._compare_obj(obj, expected) class InvalidDbusInit(AATest): tests = [ # access bus path name interface member peername peerlabel expected exception # empty fields ( ('', 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( ((), 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (DbusRule.ALL, '', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (DbusRule.ALL, 'session', '', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (DbusRule.ALL, 'session', '/org/test', '', '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (DbusRule.ALL, 'session', '/org/test', 'com.aa.test', '', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (DbusRule.ALL, 'session', '/org/test', 'com.aa.test', '/int/face', '', '/peer/name', '/peer/label'), AppArmorBug), ( (DbusRule.ALL, 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '', '/peer/label'), AppArmorBug), ( (DbusRule.ALL, 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', '' ), AppArmorBug), # whitespace fields ( (' ', 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (DbusRule.ALL, ' ', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (DbusRule.ALL, 'session', ' ', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (DbusRule.ALL, 'session', '/org/test', ' ', '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (DbusRule.ALL, 'session', '/org/test', 'com.aa.test', ' ', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (DbusRule.ALL, 'session', '/org/test', 'com.aa.test', '/int/face', ' ', '/peer/name', '/peer/label'), AppArmorBug), ( (DbusRule.ALL, 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', ' ', '/peer/label'), AppArmorBug), ( (DbusRule.ALL, 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', ' ' ), AppArmorBug), # wrong type - dict() ( (dict(), 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (('send'), dict(), '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (('send'), 'session', dict(), 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (('send'), 'session', '/org/test', dict(), '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (('send'), 'session', '/org/test', 'com.aa.test', dict(), '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (('send'), 'session', '/org/test', 'com.aa.test', '/int/face', dict(), '/peer/name', '/peer/label'), AppArmorBug), ( (('send'), 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', dict(), '/peer/label'), AppArmorBug), ( (('send'), 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', dict() ), AppArmorBug), # wrong type - None ( (None, 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( ((None), 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (('send'), None, '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (('send'), 'session', None, 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (('send'), 'session', '/org/test', None, '/int/face', '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (('send'), 'session', '/org/test', 'com.aa.test', None, '/mem/ber', '/peer/name', '/peer/label'), AppArmorBug), ( (('send'), 'session', '/org/test', 'com.aa.test', '/int/face', None, '/peer/name', '/peer/label'), AppArmorBug), ( (('send'), 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', None, '/peer/label'), AppArmorBug), ( (('send'), 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', None ), AppArmorBug), # bind conflicts with path, interface, member, peer name and peer label ( (('bind'), DbusRule.ALL, '/org/test', DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL ), AppArmorException), ( (('bind'), DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, '/int/face', DbusRule.ALL, DbusRule.ALL, DbusRule.ALL ), AppArmorException), ( (('bind'), DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, '/mem/ber', DbusRule.ALL, DbusRule.ALL ), AppArmorException), ( (('bind'), DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, '/peer/name', DbusRule.ALL ), AppArmorException), ( (('bind'), DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, '/peer/label'), AppArmorException), # eavesdrop conflcts with path, name, interface, member, peer name and peer label ( (('eavesdrop'),DbusRule.ALL, '/org/test', DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL ), AppArmorException), ( (('eavesdrop'),DbusRule.ALL, DbusRule.ALL, 'com.aa.test', DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL ), AppArmorException), ( (('eavesdrop'),DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, '/int/face', DbusRule.ALL, DbusRule.ALL, DbusRule.ALL ), AppArmorException), ( (('eavesdrop'),DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, '/mem/ber', DbusRule.ALL, DbusRule.ALL ), AppArmorException), ( (('eavesdrop'),DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, '/peer/name', DbusRule.ALL ), AppArmorException), ( (('eavesdrop'),DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, '/peer/label'), AppArmorException), # send and receive conflict with name ( (('send'), DbusRule.ALL, DbusRule.ALL, 'com.aa.test', DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL ), AppArmorException), ( (('receive'), DbusRule.ALL, DbusRule.ALL, 'com.aa.test', DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL ), AppArmorException), # misc ( (DbusRule.ALL, DbusRule.ALL, 'foo/bar', DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL ), AppArmorException), # path doesn't start with / ( (('foo'), DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL ), AppArmorException), # invalid access keyword ( (('foo', 'send'), DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL ), AppArmorException), # valid + invalid access keyword ] def _run_test(self, params, expected): with self.assertRaises(expected): DbusRule(params[0], params[1], params[2], params[3], params[4], params[5], params[6], params[7]) def test_missing_params_1(self): with self.assertRaises(TypeError): DbusRule('send') def test_missing_params_2(self): with self.assertRaises(TypeError): DbusRule(('send'), 'session') def test_missing_params_3(self): with self.assertRaises(TypeError): DbusRule(('send'), 'session', '/org/test') def test_missing_params_4(self): with self.assertRaises(TypeError): DbusRule(('send'), 'session', '/org/test', 'com.aa.test') def test_missing_params_5(self): with self.assertRaises(TypeError): DbusRule(('send'), 'session', '/org/test', 'com.aa.test', '/int/face') def test_missing_params_6(self): with self.assertRaises(TypeError): DbusRule(('send'), 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber') def test_missing_params_7(self): with self.assertRaises(TypeError): DbusRule(('send'), 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name') class InvalidDbusTest(AATest): def _check_invalid_rawrule(self, rawrule): obj = None self.assertFalse(DbusRule.match(rawrule)) with self.assertRaises(AppArmorException): obj = DbusRule(DbusRule.parse(rawrule)) self.assertIsNone(obj, 'DbusRule handed back an object unexpectedly') def test_invalid_dbus_missing_comma(self): self._check_invalid_rawrule('dbus') # missing comma def test_invalid_non_DbusRule(self): self._check_invalid_rawrule('signal,') # not a dbus rule def test_empty_data_1(self): # access bus path name interface member peername peerlabel expected exception obj = DbusRule(('send'), 'session', '/org/test', DbusRule.ALL, '/int/face', '/mem/ber', '/peer/name', '/peer/label') obj.access = '' # no access set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) def test_empty_data_2(self): obj = DbusRule(('send'), 'session', '/org/test', DbusRule.ALL, '/int/face', '/mem/ber', '/peer/name', '/peer/label') obj.bus = '' # no bus set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) def test_empty_data_3(self): obj = DbusRule(('send'), 'session', '/org/test', DbusRule.ALL, '/int/face', '/mem/ber', '/peer/name', '/peer/label') obj.path = '' # no path set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) def test_empty_data_4(self): obj = DbusRule(DbusRule.ALL, 'session', '/org/test', 'com.aa.test', '/int/face', '/mem/ber', '/peer/name', '/peer/label') obj.name = '' # no name set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) def test_empty_data_5(self): obj = DbusRule(('send'), 'session', '/org/test', DbusRule.ALL, '/int/face', '/mem/ber', '/peer/name', '/peer/label') obj.interface = '' # no interface set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) def test_empty_data_6(self): obj = DbusRule(('send'), 'session', '/org/test', DbusRule.ALL, '/int/face', '/mem/ber', '/peer/name', '/peer/label') obj.member = '' # no member set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) def test_empty_data_7(self): obj = DbusRule(('send'), 'session', '/org/test', DbusRule.ALL, '/int/face', '/mem/ber', '/peer/name', '/peer/label') obj.peername = '' # no peername set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) def test_empty_data_8(self): obj = DbusRule(('send'), 'session', '/org/test', DbusRule.ALL, '/int/face', '/mem/ber', '/peer/name', '/peer/label') obj.peerlabel = '' # no peerlabel set, and ALL not set with self.assertRaises(AppArmorBug): obj.get_clean(1) class WriteDbusTest(AATest): def _run_test(self, rawrule, expected): self.assertTrue(DbusRule.match(rawrule), 'DbusRule.match() failed') obj = DbusRule.parse(rawrule) clean = obj.get_clean() raw = obj.get_raw() self.assertEqual(expected.strip(), clean, 'unexpected clean rule') self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule') tests = [ # raw rule clean rule (' dbus , # foo ' , 'dbus, # foo'), (' audit dbus send,' , 'audit dbus send,'), (' audit dbus (send ),' , 'audit dbus send,'), (' audit dbus (send , receive ),' , 'audit dbus (receive send),'), (' deny dbus send bus=session,# foo bar' , 'deny dbus send bus=session, # foo bar'), (' deny dbus send bus=(session), ' , 'deny dbus send bus=session,'), (' deny dbus send peer=(name=unconfined label=foo),' , 'deny dbus send peer=(name=unconfined label=foo),'), (' deny dbus send interface = ( foo ),' , 'deny dbus send interface=foo,'), (' deny dbus send ,# foo bar' , 'deny dbus send, # foo bar'), (' allow dbus peer=(label=foo) ,# foo bar' , 'allow dbus peer=(label=foo), # foo bar'), ('dbus,' , 'dbus,'), ('dbus (receive),' , 'dbus receive,'), ('dbus (send),' , 'dbus send,'), ('dbus (send receive),' , 'dbus (receive send),'), ('dbus receive,' , 'dbus receive,'), ('dbus eavesdrop,' , 'dbus eavesdrop,'), ('dbus bind bus = foo name = bar,' , 'dbus bind bus=foo name=bar,'), ('dbus send peer=( label = /foo ) ,' , 'dbus send peer=(label=/foo),'), ('dbus (receive) member=baz,' , 'dbus receive member=baz,'), ('dbus send path = /foo,' , 'dbus send path=/foo,'), ('dbus receive peer=(label=foo),' , 'dbus receive peer=(label=foo),'), ('dbus (send receive) peer=(name=/usr/bin/bar),' , 'dbus (receive send) peer=(name=/usr/bin/bar),'), ('dbus (, receive ,,, send ,) interface=/sbin/baz,' , 'dbus (receive send) interface=/sbin/baz,'), # XXX leading and trailing ',' inside (...) causes error # XXX add more complex rules ] def test_write_manually_1(self): # access bus path name interface member peername peerlabel expected exception obj = DbusRule(('send'), 'session', '/org/test', DbusRule.ALL, '/int/face', '/mem/ber', '/peer/name', '/peer/label', allow_keyword=True) expected = ' allow dbus send bus=session path=/org/test interface=/int/face member=/mem/ber peer=(name=/peer/name label=/peer/label),' self.assertEqual(expected, obj.get_clean(2), 'unexpected clean rule') self.assertEqual(expected, obj.get_raw(2), 'unexpected raw rule') def test_write_manually_2(self): # access bus path name interface member peername peerlabel expected exception obj = DbusRule(('send', 'receive'), DbusRule.ALL, '/org/test', DbusRule.ALL, DbusRule.ALL, '/mem/ber', '/peer/name', DbusRule.ALL, allow_keyword=True) expected = ' allow dbus (receive send) path=/org/test member=/mem/ber peer=(name=/peer/name),' self.assertEqual(expected, obj.get_clean(2), 'unexpected clean rule') self.assertEqual(expected, obj.get_raw(2), 'unexpected raw rule') class DbusCoveredTest(AATest): def _run_test(self, param, expected): obj = DbusRule.parse(self.rule) check_obj = DbusRule.parse(param) self.assertTrue(DbusRule.match(param)) self.assertEqual(obj.is_equal(check_obj), expected[0], 'Mismatch in is_equal, expected %s' % expected[0]) self.assertEqual(obj.is_equal(check_obj, True), expected[1], 'Mismatch in is_equal/strict, expected %s' % expected[1]) self.assertEqual(obj.is_covered(check_obj), expected[2], 'Mismatch in is_covered, expected %s' % expected[2]) self.assertEqual(obj.is_covered(check_obj, True, True), expected[3], 'Mismatch in is_covered/exact, expected %s' % expected[3]) class DbusCoveredTest_01(DbusCoveredTest): rule = 'dbus send,' tests = [ # rule equal strict equal covered covered exact ('dbus,' , [ False , False , False , False ]), ('dbus send,' , [ True , True , True , True ]), ('dbus send member=unconfined,' , [ False , False , True , True ]), ('dbus send, # comment' , [ True , False , True , True ]), ('allow dbus send,' , [ True , False , True , True ]), ('dbus send,' , [ True , False , True , True ]), ('dbus send bus=session,' , [ False , False , True , True ]), ('dbus send member=(label=foo),' , [ False , False , True , True ]), ('audit dbus send,' , [ False , False , False , False ]), ('audit dbus,' , [ False , False , False , False ]), ('dbus receive,' , [ False , False , False , False ]), ('dbus member=(label=foo),' , [ False , False , False , False ]), ('audit deny dbus send,' , [ False , False , False , False ]), ('deny dbus send,' , [ False , False , False , False ]), ] class DbusCoveredTest_02(DbusCoveredTest): rule = 'audit dbus send,' tests = [ # rule equal strict equal covered covered exact ( 'dbus send,' , [ False , False , True , False ]), ('audit dbus send,' , [ True , True , True , True ]), ( 'dbus send bus=session,' , [ False , False , True , False ]), ('audit dbus send bus=session,' , [ False , False , True , True ]), ( 'dbus,' , [ False , False , False , False ]), ('audit dbus,' , [ False , False , False , False ]), ('dbus receive,' , [ False , False , False , False ]), ] class DbusCoveredTest_03(DbusCoveredTest): rule = 'dbus send bus=session,' tests = [ # rule equal strict equal covered covered exact ( 'dbus send bus=session,' , [ True , True , True , True ]), ('allow dbus send bus=session,' , [ True , False , True , True ]), ( 'dbus send,' , [ False , False , False , False ]), ( 'dbus,' , [ False , False , False , False ]), ( 'dbus send member=(label=foo),' , [ False , False , False , False ]), ('audit dbus,' , [ False , False , False , False ]), ('audit dbus send bus=session,' , [ False , False , False , False ]), ('audit dbus bus=session,' , [ False , False , False , False ]), ( 'dbus send,' , [ False , False , False , False ]), ( 'dbus,' , [ False , False , False , False ]), ] class DbusCoveredTest_04(DbusCoveredTest): rule = 'dbus,' tests = [ # rule equal strict equal covered covered exact ( 'dbus,' , [ True , True , True , True ]), ('allow dbus,' , [ True , False , True , True ]), ( 'dbus send,' , [ False , False , True , True ]), ( 'dbus receive bus=session,' , [ False , False , True , True ]), ( 'dbus member=(label=foo),' , [ False , False , True , True ]), ( 'dbus send bus=session,' , [ False , False , True , True ]), ('audit dbus,' , [ False , False , False , False ]), ('deny dbus,' , [ False , False , False , False ]), ] class DbusCoveredTest_05(DbusCoveredTest): rule = 'deny dbus send,' tests = [ # rule equal strict equal covered covered exact ( 'deny dbus send,' , [ True , True , True , True ]), ('audit deny dbus send,' , [ False , False , False , False ]), ( 'dbus send,' , [ False , False , False , False ]), # XXX should covered be true here? ( 'deny dbus receive,' , [ False , False , False , False ]), ( 'deny dbus,' , [ False , False , False , False ]), ] class DbusCoveredTest_06(DbusCoveredTest): rule = 'dbus send peer=(name=unconfined),' tests = [ # rule equal strict equal covered covered exact ('dbus,' , [ False , False , False , False ]), ('dbus send,' , [ False , False , False , False ]), ('dbus send peer=(name=unconfined),' , [ True , True , True , True ]), ('dbus peer=(name=unconfined),' , [ False , False , False , False ]), ('dbus send, # comment' , [ False , False , False , False ]), ('allow dbus send,' , [ False , False , False , False ]), ('allow dbus send peer=(name=unconfined),' , [ True , False , True , True ]), ('allow dbus send peer=(name=/foo/bar),' , [ False , False , False , False ]), ('allow dbus send peer=(name=/**),' , [ False , False , False , False ]), ('allow dbus send peer=(name=**),' , [ False , False , False , False ]), ('dbus send,' , [ False , False , False , False ]), ('dbus send peer=(name=unconfined),' , [ True , False , True , True ]), ('dbus send bus=session,' , [ False , False , False , False ]), ('dbus send peer=(name=unconfined label=foo),' , [ False , False , True , True ]), ('audit dbus send peer=(name=unconfined),' , [ False , False , False , False ]), ('audit dbus,' , [ False , False , False , False ]), ('dbus receive,' , [ False , False , False , False ]), ('dbus peer=(label=foo),' , [ False , False , False , False ]), ('audit deny dbus send,' , [ False , False , False , False ]), ('deny dbus send,' , [ False , False , False , False ]), ] class DbusCoveredTest_07(DbusCoveredTest): rule = 'dbus send peer=(label=unconfined),' tests = [ # rule equal strict equal covered covered exact ('dbus,' , [ False , False , False , False ]), ('dbus send,' , [ False , False , False , False ]), ('dbus send peer=(label=unconfined),' , [ True , True , True , True ]), ('dbus peer=(label=unconfined),' , [ False , False , False , False ]), ('dbus send, # comment' , [ False , False , False , False ]), ('allow dbus send,' , [ False , False , False , False ]), ('allow dbus send peer=(label=unconfined),' , [ True , False , True , True ]), ('allow dbus send peer=(label=/foo/bar),' , [ False , False , False , False ]), ('allow dbus send peer=(label=/**),' , [ False , False , False , False ]), ('allow dbus send peer=(label=**),' , [ False , False , False , False ]), ('dbus send,' , [ False , False , False , False ]), ('dbus send peer=(label=unconfined),' , [ True , False , True , True ]), ('dbus send bus=session,' , [ False , False , False , False ]), ('dbus send peer=(label=unconfined name=foo),' , [ False , False , True , True ]), ('audit dbus send peer=(label=unconfined),' , [ False , False , False , False ]), ('audit dbus,' , [ False , False , False , False ]), ('dbus receive,' , [ False , False , False , False ]), ('dbus peer=(label=foo),' , [ False , False , False , False ]), ('audit deny dbus send,' , [ False , False , False , False ]), ('deny dbus send,' , [ False , False , False , False ]), ] class DbusCoveredTest_08(DbusCoveredTest): rule = 'dbus send path=/foo/bar,' tests = [ # rule equal strict equal covered covered exact ('dbus,' , [ False , False , False , False ]), ('dbus send,' , [ False , False , False , False ]), ('dbus send path=/foo/bar,' , [ True , True , True , True ]), ('dbus send path=/foo/*,' , [ False , False , False , False ]), ('dbus send path=/**,' , [ False , False , False , False ]), ('dbus send path=/what/*,' , [ False , False , False , False ]), ('dbus path=/foo/bar,' , [ False , False , False , False ]), ('dbus send, # comment' , [ False , False , False , False ]), ('allow dbus send,' , [ False , False , False , False ]), ('allow dbus send path=/foo/bar,' , [ True , False , True , True ]), ('dbus send,' , [ False , False , False , False ]), ('dbus send path=/foo/bar,' , [ True , False , True , True ]), ('dbus send path=/what/ever,' , [ False , False , False , False ]), ('dbus send bus=session,' , [ False , False , False , False ]), ('dbus send path=/foo/bar peer=(label=foo),' , [ False , False , True , True ]), ('audit dbus send path=/foo/bar,' , [ False , False , False , False ]), ('audit dbus,' , [ False , False , False , False ]), ('dbus receive,' , [ False , False , False , False ]), ('dbus peer=(label=foo),' , [ False , False , False , False ]), ('audit deny dbus send,' , [ False , False , False , False ]), ('deny dbus send,' , [ False , False , False , False ]), ] class DbusCoveredTest_09(DbusCoveredTest): rule = 'dbus send member=**,' tests = [ # rule equal strict equal covered covered exact ('dbus,' , [ False , False , False , False ]), ('dbus send,' , [ False , False , False , False ]), ('dbus send member=/foo/bar,' , [ False , False , True , True ]), ('dbus send member=/foo/*,' , [ False , False , True , True ]), ('dbus send member=/**,' , [ False , False , True , True ]), ('dbus send member=/what/*,' , [ False , False , True , True ]), ('dbus member=/foo/bar,' , [ False , False , False , False ]), ('dbus send, # comment' , [ False , False , False , False ]), ('allow dbus send,' , [ False , False , False , False ]), ('allow dbus send member=/foo/bar,' , [ False , False , True , True ]), ('dbus send,' , [ False , False , False , False ]), ('dbus send member=/foo/bar,' , [ False , False , True , True ]), ('dbus send member=/what/ever,' , [ False , False , True , True ]), ('dbus send bus=session,' , [ False , False , False , False ]), ('dbus send member=/foo/bar peer=(label=foo),' , [ False , False , True , True ]), ('audit dbus send member=/foo/bar,' , [ False , False , False , False ]), ('audit dbus,' , [ False , False , False , False ]), ('dbus receive,' , [ False , False , False , False ]), ('dbus member=(label=foo),' , [ False , False , False , False ]), ('audit deny dbus send,' , [ False , False , False , False ]), ('deny dbus send,' , [ False , False , False , False ]), ] class DbusCoveredTest_10(DbusCoveredTest): rule = 'dbus (send, receive) interface=foo,' tests = [ # rule equal strict equal covered covered exact ('dbus,' , [ False , False , False , False ]), ('dbus send,' , [ False , False , False , False ]), ('dbus send interface=foo,' , [ False , False , True , True ]), ('dbus receive bus=session interface=foo,' , [ False , False , True , True ]), ('dbus (receive,send) interface=foo,' , [ True , False , True , True ]), ('dbus (receive,send),' , [ False , False , False , False ]), ('dbus send bus=session,' , [ False , False , False , False ]), ('dbus send member=/foo/bar,' , [ False , False , False , False ]), ('dbus send member=/foo/*,' , [ False , False , False , False ]), ('dbus send member=/**,' , [ False , False , False , False ]), ('dbus send member=/what/*,' , [ False , False , False , False ]), ('dbus member=/foo/bar,' , [ False , False , False , False ]), ('dbus send, # comment' , [ False , False , False , False ]), ('allow dbus send,' , [ False , False , False , False ]), ('allow dbus send member=/foo/bar,' , [ False , False , False , False ]), ('dbus send,' , [ False , False , False , False ]), ('dbus send member=/foo/bar,' , [ False , False , False , False ]), ('dbus send member=/what/ever,' , [ False , False , False , False ]), ('dbus send bus=session,' , [ False , False , False , False ]), ('dbus send bus=session interface=foo,' , [ False , False , True , True ]), ('dbus send member=/foo/bar peer=(label=foo),' , [ False , False , False , False ]), ('audit dbus send member=/foo/bar,' , [ False , False , False , False ]), ('audit dbus,' , [ False , False , False , False ]), ('dbus receive,' , [ False , False , False , False ]), ('dbus peer=(label=foo),' , [ False , False , False , False ]), ('audit deny dbus send,' , [ False , False , False , False ]), ('deny dbus send,' , [ False , False , False , False ]), ] class DbusCoveredTest_11(DbusCoveredTest): rule = 'dbus name=/foo/bar,' tests = [ # rule equal strict equal covered covered exact ('dbus,' , [ False , False , False , False ]), ('dbus name=/foo/bar,' , [ True , True , True , True ]), ('dbus name=/foo/*,' , [ False , False , False , False ]), ('dbus name=/**,' , [ False , False , False , False ]), ('dbus name=/what/*,' , [ False , False , False , False ]), ('dbus, # comment' , [ False , False , False , False ]), ('allow dbus,' , [ False , False , False , False ]), ('allow dbus name=/foo/bar,' , [ True , False , True , True ]), ('dbus ,' , [ False , False , False , False ]), ('dbus name=/foo/bar,' , [ True , False , True , True ]), ('dbus name=/what/ever,' , [ False , False , False , False ]), ('dbus bus=session,' , [ False , False , False , False ]), ('dbus name=/foo/bar peer=(label=foo),' , [ False , False , True , True ]), ('audit dbus name=/foo/bar,' , [ False , False , False , False ]), ('audit dbus,' , [ False , False , False , False ]), ('dbus receive,' , [ False , False , False , False ]), ('dbus peer=(label=foo),' , [ False , False , False , False ]), ('audit deny dbus,' , [ False , False , False , False ]), ('deny dbus,' , [ False , False , False , False ]), ] class DbusCoveredTest_Invalid(AATest): def AASetup(self): # access bus path name interface member peername peerlabel expected exception self.obj = DbusRule(('send', 'receive'), 'session', '/org/test', DbusRule.ALL, '/int/face', DbusRule.ALL, '/peer/name', '/peer/label', allow_keyword=True) self.testobj = DbusRule(('send'), 'session', '/org/test', DbusRule.ALL, '/int/face', '/mem/ber', '/peer/name', '/peer/label', allow_keyword=True) def test_borked_obj_is_covered_1(self): self.testobj.access = '' with self.assertRaises(AppArmorBug): self.obj.is_covered(self.testobj) def test_borked_obj_is_covered_2(self): self.testobj.bus = '' with self.assertRaises(AppArmorBug): self.obj.is_covered(self.testobj) def test_borked_obj_is_covered_3(self): self.testobj.path = '' with self.assertRaises(AppArmorBug): self.obj.is_covered(self.testobj) def test_borked_obj_is_covered_4(self): # we need a different 'victim' because dbus send doesn't allow the name conditional we want to test here self.obj = DbusRule(('bind'), 'session', DbusRule.ALL, '/name', DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, allow_keyword=True) self.testobj = DbusRule(('bind'), 'session', DbusRule.ALL, '/name', DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, DbusRule.ALL, allow_keyword=True) self.testobj.name = '' with self.assertRaises(AppArmorBug): self.obj.is_covered(self.testobj) def test_borked_obj_is_covered_5(self): self.testobj.interface = '' with self.assertRaises(AppArmorBug): self.obj.is_covered(self.testobj) def test_borked_obj_is_covered_6(self): self.testobj.member = '' with self.assertRaises(AppArmorBug): self.obj.is_covered(self.testobj) def test_borked_obj_is_covered_7(self): self.testobj.peername = '' with self.assertRaises(AppArmorBug): self.obj.is_covered(self.testobj) def test_borked_obj_is_covered_8(self): self.testobj.peerlabel = '' with self.assertRaises(AppArmorBug): self.obj.is_covered(self.testobj) def test_invalid_is_covered(self): obj = DbusRule.parse('dbus send,') testobj = BaseRule() # different type with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_invalid_is_equal(self): obj = DbusRule.parse('dbus send,') testobj = BaseRule() # different type with self.assertRaises(AppArmorBug): obj.is_equal(testobj) class DbusLogprofHeaderTest(AATest): tests = [ ('dbus,', [ _('Access mode'), _('ALL'), _('Bus'), _('ALL'), _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), _('ALL')]), ('dbus (send receive),', [ _('Access mode'), 'receive send', _('Bus'), _('ALL'), _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), _('ALL')]), ('dbus send bus=session,', [ _('Access mode'), 'send', _('Bus'), 'session', _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), _('ALL')]), ('deny dbus,', [_('Qualifier'), 'deny', _('Access mode'), _('ALL'), _('Bus'), _('ALL'), _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), _('ALL')]), ('allow dbus send,', [_('Qualifier'), 'allow', _('Access mode'), 'send', _('Bus'), _('ALL'), _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), _('ALL')]), ('audit dbus send bus=session,', [_('Qualifier'), 'audit', _('Access mode'), 'send', _('Bus'), 'session', _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), _('ALL')]), ('audit deny dbus send,', [_('Qualifier'), 'audit deny', _('Access mode'), 'send', _('Bus'), _('ALL'), _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), _('ALL')]), ('dbus bind name=bind.name,', [ _('Access mode'), 'bind', _('Bus'), _('ALL'), _('Path'), _('ALL'), _('Name'), 'bind.name', _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), _('ALL')]), ('dbus send bus=session path=/path interface=aa.test member=ExMbr peer=(name=(peer.name)),', [ _('Access mode'), 'send', _('Bus'), 'session', _('Path'), '/path', _('Name'), _('ALL'), _('Interface'), 'aa.test', _('Member'), 'ExMbr', _('Peer name'), 'peer.name',_('Peer label'), _('ALL')]), ('dbus send peer=(label=foo),', [ _('Access mode'), 'send', _('Bus'), _('ALL'), _('Path'), _('ALL'), _('Name'), _('ALL'), _('Interface'), _('ALL'), _('Member'), _('ALL'), _('Peer name'), _('ALL'), _('Peer label'), 'foo' ]), ] def _run_test(self, params, expected): obj = DbusRule._parse(params) self.assertEqual(obj.logprof_header(), expected) ## --- tests for DbusRuleset --- # class DbusRulesTest(AATest): def test_empty_ruleset(self): ruleset = DbusRuleset() ruleset_2 = DbusRuleset() self.assertEqual([], ruleset.get_raw(2)) self.assertEqual([], ruleset.get_clean(2)) self.assertEqual([], ruleset_2.get_raw(2)) self.assertEqual([], ruleset_2.get_clean(2)) def test_ruleset_1(self): ruleset = DbusRuleset() rules = [ 'dbus peer=(label=foo),', 'dbus send,', ] expected_raw = [ 'dbus peer=(label=foo),', 'dbus send,', '', ] expected_clean = [ 'dbus peer=(label=foo),', 'dbus send,', '', ] for rule in rules: ruleset.add(DbusRule.parse(rule)) self.assertEqual(expected_raw, ruleset.get_raw()) self.assertEqual(expected_clean, ruleset.get_clean()) def test_ruleset_2(self): ruleset = DbusRuleset() rules = [ 'dbus send peer=(label=foo),', 'allow dbus send,', 'deny dbus bus=session, # example comment', ] expected_raw = [ ' dbus send peer=(label=foo),', ' allow dbus send,', ' deny dbus bus=session, # example comment', '', ] expected_clean = [ ' deny dbus bus=session, # example comment', '', ' allow dbus send,', ' dbus send peer=(label=foo),', '', ] for rule in rules: ruleset.add(DbusRule.parse(rule)) self.assertEqual(expected_raw, ruleset.get_raw(1)) self.assertEqual(expected_clean, ruleset.get_clean(1)) class DbusGlobTest(AATest): def setUp(self): self.maxDiff = None self.ruleset = DbusRuleset() def test_glob_1(self): self.assertEqual(self.ruleset.get_glob('dbus send,'), 'dbus,') # not supported or used yet # def test_glob_2(self): # self.assertEqual(self.ruleset.get_glob('dbus send raw,'), 'dbus send,') def test_glob_ext(self): with self.assertRaises(NotImplementedError): # get_glob_ext is not available for dbus rules self.ruleset.get_glob_ext('dbus send peer=(label=foo),') #class DbusDeleteTest(AATest): # pass setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-translations.py0000644000175000017500000001231313502024172017374 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2016 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import unittest from common_test import AATest, setup_all_loops import gettext import os import subprocess from apparmor.ui import CMDS, get_translated_hotkey class TestHotkeyConflicts(AATest): # check if there are any hotkey conflicts in one of the apparmor-utils translations tests = [ (['CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_OFF', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py available_buttons() with CMD_AUDIT_OFF (['CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_NEW', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py available_buttons() with CMD_AUDIT_NEW (['CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_OFF', 'CMD_USER_ON', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py available_buttons() with CMD_AUDIT_OFF and CMD_USER_ON (['CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_OFF', 'CMD_USER_OFF', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py available_buttons() with CMD_AUDIT_OFF and CMD_USER_OFF (['CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_NEW', 'CMD_USER_ON', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py available_buttons() with CMD_AUDIT_NEW and CMD_USER_ON (['CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_NEW', 'CMD_USER_OFF', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py available_buttons() with CMD_AUDIT_NEW and CMD_USER_OFF (['CMD_SAVE_CHANGES', 'CMD_SAVE_SELECTED', 'CMD_VIEW_CHANGES', 'CMD_VIEW_CHANGES_CLEAN', 'CMD_ABORT'], True), # aa.py save_profiles() (['CMD_VIEW_PROFILE', 'CMD_USE_PROFILE', 'CMD_CREATE_PROFILE', 'CMD_ABORT'], True), # aa.py get_profile() (['CMD_UPLOAD_CHANGES', 'CMD_VIEW_CHANGES', 'CMD_ASK_LATER', 'CMD_ASK_NEVER', 'CMD_ABORT'], True), # aa.py console_select_and_upload_profiles() (['CMD_ix', 'CMD_pix', 'CMD_cix', 'CMD_nix', 'CMD_EXEC_IX_OFF', 'CMD_ux', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py build_x_functions() with exec_toggle (['CMD_ix', 'CMD_cx', 'CMD_px', 'CMD_nx', 'CMD_ux', 'CMD_EXEC_IX_ON', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py build_x_functions() without exec_toggle (['CMD_ADDHAT', 'CMD_USEDEFAULT', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa.py handle_children() (['CMD_YES', 'CMD_NO', 'CMD_CANCEL'], True), # ui.py UI_YesNo() and UI_YesNoCancel (['CMD_SAVE_CHANGES', 'CMD_VIEW_CHANGES', 'CMD_ABORT', 'CMD_IGNORE_ENTRY'], True), # aa-mergeprof act() (['CMD_ALLOW', 'CMD_ABORT'], True), # aa-mergeprof conflict_mode() (['CMD_ADDSUBPROFILE', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa-mergeprof ask_the_questions() - new subprofile (['CMD_ADDHAT', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'], True), # aa-mergeprof ask_the_questions() - new hat ] def _run_test(self, params, expected): self.createTmpdir() subprocess.call("make -C ../po >/dev/null", shell=True) subprocess.call("DESTDIR=%s NAME=apparmor-utils make -C ../po install >/dev/null" % self.tmpdir, shell=True) self.localedir = '%s/usr/share/locale' % self.tmpdir self.languages = os.listdir(self.localedir) # make sure we found all translations if len(self.languages) < 15: raise Exception('None or not all languages found, only %s' % self.languages) self.languages.append('C') # we also want to detect hotkey conflicts in the untranslated english strings for language in self.languages: t = gettext.translation('apparmor-utils', fallback=True, localedir=self.localedir, languages=[language]) keys = dict() for key in params: text = t.gettext(CMDS[key]) hotkey = get_translated_hotkey(text) if keys.get(hotkey): raise Exception("Hotkey conflict: '%s' and '%s' in language %s" % (keys[hotkey], text, language)) else: keys[hotkey] = text setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-aa-easyprof.py0000755000175000017500000027332213502024172017076 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2011-2015 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import glob import json import optparse import os import shutil import sys import tempfile import unittest import apparmor.easyprof as easyprof topdir = None debugging = False def recursive_rm(dirPath, contents_only=False): '''recursively remove directory''' names = os.listdir(dirPath) for name in names: path = os.path.join(dirPath, name) if os.path.islink(path) or not os.path.isdir(path): os.unlink(path) else: recursive_rm(path) if contents_only == False: os.rmdir(dirPath) # From Lib/test/test_optparse.py from python 2.7.4 class InterceptedError(Exception): def __init__(self, error_message=None, exit_status=None, exit_message=None): self.error_message = error_message self.exit_status = exit_status self.exit_message = exit_message def __str__(self): return self.error_message or self.exit_message or "intercepted error" class InterceptingOptionParser(optparse.OptionParser): def exit(self, status=0, msg=None): raise InterceptedError(exit_status=status, exit_message=msg) def error(self, msg): raise InterceptedError(error_message=msg) class Manifest(object): def __init__(self, profile_name): self.security = dict() self.security['profiles'] = dict() self.profile_name = profile_name self.security['profiles'][self.profile_name] = dict() def add_policygroups(self, policy_list): self.security['profiles'][self.profile_name]['policy_groups'] = policy_list.split(",") def add_author(self, author): self.security['profiles'][self.profile_name]['author'] = author def add_copyright(self, copyright): self.security['profiles'][self.profile_name]['copyright'] = copyright def add_comment(self, comment): self.security['profiles'][self.profile_name]['comment'] = comment def add_binary(self, binary): self.security['profiles'][self.profile_name]['binary'] = binary def add_template(self, template): self.security['profiles'][self.profile_name]['template'] = template def add_template_variable(self, name, value): if not 'template_variables' in self.security['profiles'][self.profile_name]: self.security['profiles'][self.profile_name]['template_variables'] = dict() self.security['profiles'][self.profile_name]['template_variables'][name] = value def emit_json(self, use_security_prefix=True): manifest = dict() manifest['security'] = self.security if use_security_prefix: dumpee = manifest else: dumpee = self.security return json.dumps(dumpee, indent=2) # # Our test class # class T(unittest.TestCase): # work around UsrMove ls = os.path.realpath('/bin/ls') def setUp(self): '''Setup for tests''' global topdir self.tmpdir = os.path.realpath(tempfile.mkdtemp(prefix='test-aa-easyprof')) # Copy everything into place for d in ['easyprof/policygroups', 'easyprof/templates']: shutil.copytree(os.path.join(topdir, d), os.path.join(self.tmpdir, os.path.basename(d))) # Create a test template self.test_template = "test-template" contents = '''# vim:syntax=apparmor # %s # AppArmor policy for ###NAME### # ###AUTHOR### # ###COPYRIGHT### # ###COMMENT### #include ###VAR### ###PROFILEATTACH### { #include ###ABSTRACTIONS### ###POLICYGROUPS### ###READS### ###WRITES### } ''' % (self.test_template) open(os.path.join(self.tmpdir, 'templates', self.test_template), 'w').write(contents) # Create a test policygroup self.test_policygroup = "test-policygroup" contents = ''' # %s #include #include ''' % (self.test_policygroup) open(os.path.join(self.tmpdir, 'policygroups', self.test_policygroup), 'w').write(contents) # setup our conffile self.conffile = os.path.join(self.tmpdir, 'easyprof.conf') contents = ''' POLICYGROUPS_DIR="%s/policygroups" TEMPLATES_DIR="%s/templates" ''' % (self.tmpdir, self.tmpdir) open(self.conffile, 'w').write(contents) self.binary = "/opt/bin/foo" self.full_args = ['-c', self.conffile, self.binary] # Check __AA_BASEDIR, which may be set by the Makefile, to see if # we should use a non-default base directory path to find # abstraction files # # NOTE: Individual tests can append another --base path to the # args list and override a base path set here base = os.getenv('__AA_BASEDIR') if base: self.full_args.append('--base=%s' % base) # Check __AA_PARSER, which may be set by the Makefile, to see if # we should use a non-default apparmor_parser path to verify # policy parser = os.getenv('__AA_PARSER') if parser: self.full_args.append('--parser=%s' % parser) if debugging: self.full_args.append('-d') (self.options, self.args) = easyprof.parse_args(self.full_args + [self.binary]) # Now create some differently prefixed files in the include-dir self.test_include_dir = os.path.join(self.tmpdir, 'include-dir') os.mkdir(self.test_include_dir) os.mkdir(os.path.join(self.test_include_dir, "templates")) os.mkdir(os.path.join(self.test_include_dir, "policygroups")) for d in ['policygroups', 'templates']: for f in easyprof.get_directory_contents(os.path.join( self.tmpdir, d)): shutil.copy(f, os.path.join(self.test_include_dir, d, "inc_%s" % os.path.basename(f))) def tearDown(self): '''Teardown for tests''' if os.path.exists(self.tmpdir): if debugging: sys.stdout.write("%s\n" % self.tmpdir) else: recursive_rm(self.tmpdir) # # config file tests # def test_configuration_file_p_invalid(self): '''Test config parsing (invalid POLICYGROUPS_DIR)''' contents = ''' POLICYGROUPS_DIR= TEMPLATES_DIR="%s/templates" ''' % (self.tmpdir) open(self.conffile, 'w').write(contents) try: easyprof.AppArmorEasyProfile(self.binary, self.options) except easyprof.AppArmorException: return except Exception: raise raise Exception ("File should have been invalid") def test_configuration_file_p_empty(self): '''Test config parsing (empty POLICYGROUPS_DIR)''' contents = ''' POLICYGROUPS_DIR="%s" TEMPLATES_DIR="%s/templates" ''' % ('', self.tmpdir) open(self.conffile, 'w').write(contents) try: easyprof.AppArmorEasyProfile(self.binary, self.options) except easyprof.AppArmorException: return except Exception: raise raise Exception ("File should have been invalid") def test_configuration_file_p_nonexistent(self): '''Test config parsing (nonexistent POLICYGROUPS_DIR)''' contents = ''' POLICYGROUPS_DIR="%s/policygroups" TEMPLATES_DIR="%s/templates" ''' % ('/nonexistent', self.tmpdir) open(self.conffile, 'w').write(contents) try: easyprof.AppArmorEasyProfile(self.binary, self.options) except easyprof.AppArmorException: return except Exception: raise raise Exception ("File should have been invalid") def test_policygroups_dir_relative(self): '''Test --policy-groups-dir (relative DIR)''' os.chdir(self.tmpdir) rel = os.path.join(self.tmpdir, 'relative') os.mkdir(rel) shutil.copy(os.path.join(self.tmpdir, 'policygroups', self.test_policygroup), os.path.join(rel, self.test_policygroup)) args = self.full_args args += ['--policy-groups-dir', './relative', '--show-policy-group', '--policy-groups=%s' % self.test_policygroup] (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(self.binary, self.options) # no fallback self.assertTrue(easyp.dirs['policygroups'] == rel, "Not using specified --policy-groups-dir\n" + "Specified dir: %s\nActual dir: %s" % (rel, str(easyp.dirs['policygroups']))) self.assertFalse(easyp.get_policy_groups() == None, "Could not find policy-groups") def test_policygroups_dir_nonexistent(self): '''Test --policy-groups-dir (nonexistent DIR)''' os.chdir(self.tmpdir) rel = os.path.join(self.tmpdir, 'nonexistent') args = self.full_args args += ['--policy-groups-dir', rel, '--show-policy-group', '--policy-groups=%s' % self.test_policygroup] (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(self.binary, self.options) # test if using fallback self.assertFalse(easyp.dirs['policygroups'] == rel, "Using nonexistent --policy-groups-dir") # test fallback self.assertTrue(easyp.get_policy_groups() != None, "Found policy-groups when shouldn't have") def test_policygroups_dir_valid(self): '''Test --policy-groups-dir (valid DIR)''' os.chdir(self.tmpdir) valid = os.path.join(self.tmpdir, 'valid') os.mkdir(valid) shutil.copy(os.path.join(self.tmpdir, 'policygroups', self.test_policygroup), os.path.join(valid, self.test_policygroup)) args = self.full_args args += ['--policy-groups-dir', valid, '--show-policy-group', '--policy-groups=%s' % self.test_policygroup] (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(self.binary, self.options) # no fallback self.assertTrue(easyp.dirs['policygroups'] == valid, "Not using specified --policy-groups-dir") self.assertFalse(easyp.get_policy_groups() == None, "Could not find policy-groups") def test_policygroups_dir_valid_with_vendor(self): '''Test --policy-groups-dir (valid DIR with vendor)''' os.chdir(self.tmpdir) valid = os.path.join(self.tmpdir, 'valid') os.mkdir(valid) shutil.copy(os.path.join(self.tmpdir, 'policygroups', self.test_policygroup), os.path.join(valid, self.test_policygroup)) vendor = "ubuntu" version = "1.0" valid_distro = os.path.join(valid, vendor, version) os.mkdir(os.path.join(valid, vendor)) os.mkdir(valid_distro) shutil.copy(os.path.join(self.tmpdir, 'policygroups', self.test_policygroup), valid_distro) args = self.full_args args += ['--policy-groups-dir', valid, '--show-policy-group', '--policy-groups=%s' % self.test_policygroup] (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(self.binary, self.options) self.assertTrue(easyp.dirs['policygroups'] == valid, "Not using specified --policy-groups-dir") self.assertFalse(easyp.get_policy_groups() == None, "Could not find policy-groups") for f in easyp.get_policy_groups(): self.assertFalse(os.path.basename(f) == vendor, "Found '%s' in %s" % (vendor, f)) def test_configuration_file_t_invalid(self): '''Test config parsing (invalid TEMPLATES_DIR)''' contents = ''' TEMPLATES_DIR= POLICYGROUPS_DIR="%s/templates" ''' % (self.tmpdir) open(self.conffile, 'w').write(contents) try: easyprof.AppArmorEasyProfile(self.binary, self.options) except easyprof.AppArmorException: return except Exception: raise raise Exception ("File should have been invalid") def test_configuration_file_t_empty(self): '''Test config parsing (empty TEMPLATES_DIR)''' contents = ''' TEMPLATES_DIR="%s" POLICYGROUPS_DIR="%s/templates" ''' % ('', self.tmpdir) open(self.conffile, 'w').write(contents) try: easyprof.AppArmorEasyProfile(self.binary, self.options) except easyprof.AppArmorException: return except Exception: raise raise Exception ("File should have been invalid") def test_configuration_file_t_nonexistent(self): '''Test config parsing (nonexistent TEMPLATES_DIR)''' contents = ''' TEMPLATES_DIR="%s/policygroups" POLICYGROUPS_DIR="%s/templates" ''' % ('/nonexistent', self.tmpdir) open(self.conffile, 'w').write(contents) try: easyprof.AppArmorEasyProfile(self.binary, self.options) except easyprof.AppArmorException: return except Exception: raise raise Exception ("File should have been invalid") def test_templates_dir_relative(self): '''Test --templates-dir (relative DIR)''' os.chdir(self.tmpdir) rel = os.path.join(self.tmpdir, 'relative') os.mkdir(rel) shutil.copy(os.path.join(self.tmpdir, 'templates', self.test_template), os.path.join(rel, self.test_template)) args = self.full_args args += ['--templates-dir', './relative', '--show-template', '--template=%s' % self.test_template] (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(self.binary, self.options) # no fallback self.assertTrue(easyp.dirs['templates'] == rel, "Not using specified --template-dir\n" + "Specified dir: %s\nActual dir: %s" % (rel, str(easyp.dirs['templates']))) self.assertFalse(easyp.get_templates() == None, "Could not find templates") def test_templates_dir_nonexistent(self): '''Test --templates-dir (nonexistent DIR)''' os.chdir(self.tmpdir) rel = os.path.join(self.tmpdir, 'nonexistent') args = self.full_args args += ['--templates-dir', rel, '--show-template', '--template=%s' % self.test_template] (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(self.binary, self.options) # test if using fallback self.assertFalse(easyp.dirs['templates'] == rel, "Using nonexistent --template-dir") # test fallback self.assertTrue(easyp.get_templates() != None, "Found templates when shouldn't have") def test_templates_dir_valid(self): '''Test --templates-dir (valid DIR)''' os.chdir(self.tmpdir) valid = os.path.join(self.tmpdir, 'valid') os.mkdir(valid) shutil.copy(os.path.join(self.tmpdir, 'templates', self.test_template), os.path.join(valid, self.test_template)) args = self.full_args args += ['--templates-dir', valid, '--show-template', '--template=%s' % self.test_template] (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(self.binary, self.options) # no fallback self.assertTrue(easyp.dirs['templates'] == valid, "Not using specified --template-dir") self.assertFalse(easyp.get_templates() == None, "Could not find templates") def test_templates_dir_valid_with_vendor(self): '''Test --templates-dir (valid DIR with vendor)''' os.chdir(self.tmpdir) valid = os.path.join(self.tmpdir, 'valid') os.mkdir(valid) shutil.copy(os.path.join(self.tmpdir, 'templates', self.test_template), os.path.join(valid, self.test_template)) vendor = "ubuntu" version = "1.0" valid_distro = os.path.join(valid, vendor, version) os.mkdir(os.path.join(valid, vendor)) os.mkdir(valid_distro) shutil.copy(os.path.join(self.tmpdir, 'templates', self.test_template), valid_distro) args = self.full_args args += ['--templates-dir', valid, '--show-template', '--template=%s' % self.test_template] (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(self.binary, self.options) self.assertTrue(easyp.dirs['templates'] == valid, "Not using specified --template-dir") self.assertFalse(easyp.get_templates() == None, "Could not find templates") for f in easyp.get_templates(): self.assertFalse(os.path.basename(f) == vendor, "Found '%s' in %s" % (vendor, f)) # # Binary file tests # def test_binary_without_profile_name(self): '''Test binary ( { })''' easyprof.AppArmorEasyProfile(self.ls, self.options) def test_binary_with_profile_name(self): '''Test binary (profile { })''' args = self.full_args args += ['--profile-name=some-profile-name'] (self.options, self.args) = easyprof.parse_args(args) easyprof.AppArmorEasyProfile(self.ls, self.options) def test_binary_omitted_with_profile_name(self): '''Test binary (profile { })''' args = self.full_args args += ['--profile-name=some-profile-name'] (self.options, self.args) = easyprof.parse_args(args) easyprof.AppArmorEasyProfile(None, self.options) def test_binary_nonexistent(self): '''Test binary (nonexistent)''' easyprof.AppArmorEasyProfile(os.path.join(self.tmpdir, 'nonexistent'), self.options) def test_binary_relative(self): '''Test binary (relative)''' try: easyprof.AppArmorEasyProfile('./foo', self.options) except easyprof.AppArmorException: return except Exception: raise raise Exception ("Binary should have been invalid") def test_binary_symlink(self): '''Test binary (symlink)''' exe = os.path.join(self.tmpdir, 'exe') open(exe, 'a').close() symlink = exe + ".lnk" os.symlink(exe, symlink) try: easyprof.AppArmorEasyProfile(symlink, self.options) except easyprof.AppArmorException: return except Exception: raise raise Exception ("Binary should have been invalid") # # Templates tests # def test_templates_list(self): '''Test templates (list)''' args = self.full_args args.append('--list-templates') (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) for i in easyp.get_templates(): self.assertTrue(os.path.exists(i), "Could not find '%s'" % i) def test_templates_show(self): '''Test templates (show)''' files = [] for f in glob.glob("%s/templates/*" % self.tmpdir): files.append(f) for f in files: args = self.full_args args += ['--show-template', '--template', f] (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) path = os.path.join(easyp.dirs['templates'], f) self.assertTrue(os.path.exists(path), "Could not find '%s'" % path) open(path).read() def test_templates_list_include(self): '''Test templates (list with --include-templates-dir)''' args = self.full_args args.append('--list-templates') (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) orig_templates = easyp.get_templates() args = self.full_args args.append('--list-templates') args.append('--include-templates-dir=%s' % os.path.join(self.test_include_dir, 'templates')) (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) inc_templates = easyp.get_templates() self.assertTrue(len(inc_templates) == len(orig_templates) * 2, "templates missing: %s" % inc_templates) for i in inc_templates: self.assertTrue(os.path.exists(i), "Could not find '%s'" % i) def test_templates_show_include(self): '''Test templates (show with --include-templates-dir)''' files = [] for f in glob.glob("%s/templates/*" % self.test_include_dir): files.append(f) for f in files: args = self.full_args args += ['--show-template', '--template', f, '--include-templates-dir=%s' % os.path.join(self.test_include_dir, 'templates')] (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) path = os.path.join(easyp.dirs['templates_include'], f) self.assertTrue(os.path.exists(path), "Could not find '%s'" % path) open(path).read() bn = os.path.basename(f) # setup() copies everything in the include prefixed with inc_ self.assertTrue(bn.startswith('inc_'), "'%s' does not start with 'inc_'" % bn) # # Policygroups tests # def test_policygroups_list(self): '''Test policygroups (list)''' args = self.full_args args.append('--list-policy-groups') (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) for i in easyp.get_policy_groups(): self.assertTrue(os.path.exists(i), "Could not find '%s'" % i) def test_policygroups_show(self): '''Test policygroups (show)''' files = [] for f in glob.glob("%s/policygroups/*" % self.tmpdir): files.append(f) for f in files: args = self.full_args args += ['--show-policy-group', '--policy-groups', os.path.basename(f)] (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) path = os.path.join(easyp.dirs['policygroups'], f) self.assertTrue(os.path.exists(path), "Could not find '%s'" % path) open(path).read() def test_policygroups_list_include(self): '''Test policygroups (list with --include-policy-groups-dir)''' args = self.full_args args.append('--list-policy-groups') (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) orig_policy_groups = easyp.get_policy_groups() args = self.full_args args.append('--list-policy-groups') args.append('--include-policy-groups-dir=%s' % os.path.join(self.test_include_dir, 'policygroups')) (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) inc_policy_groups = easyp.get_policy_groups() self.assertTrue(len(inc_policy_groups) == len(orig_policy_groups) * 2, "policy_groups missing: %s" % inc_policy_groups) for i in inc_policy_groups: self.assertTrue(os.path.exists(i), "Could not find '%s'" % i) def test_policygroups_show_include(self): '''Test policygroups (show with --include-policy-groups-dir)''' files = [] for f in glob.glob("%s/policygroups/*" % self.test_include_dir): files.append(f) for f in files: args = self.full_args args += ['--show-policy-group', '--policy-groups', os.path.basename(f), '--include-policy-groups-dir=%s' % os.path.join(self.test_include_dir, 'policygroups')] (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) path = os.path.join(easyp.dirs['policygroups_include'], f) self.assertTrue(os.path.exists(path), "Could not find '%s'" % path) open(path).read() bn = os.path.basename(f) # setup() copies everything in the include prefixed with inc_ self.assertTrue(bn.startswith('inc_'), "'%s' does not start with 'inc_'" % bn) # # Manifest file argument tests # def test_manifest_argument(self): '''Test manifest argument''' # setup our manifest self.manifest = os.path.join(self.tmpdir, 'manifest.json') contents = ''' {"security": {"domain.reverse.appname": {"name": "simple-app"}}} ''' open(self.manifest, 'w').write(contents) args = self.full_args args.extend(['--manifest', self.manifest]) easyprof.parse_args(args) def _manifest_conflicts(self, opt, value): '''Helper for conflicts tests''' # setup our manifest self.manifest = os.path.join(self.tmpdir, 'manifest.json') contents = ''' {"security": {"domain.reverse.appname": {"binary": /nonexistent"}}} ''' open(self.manifest, 'w').write(contents) # opt first args = self.full_args args.extend([opt, value, '--manifest', self.manifest]) raised = False try: easyprof.parse_args(args, InterceptingOptionParser()) except InterceptedError: raised = True self.assertTrue(raised, msg="%s and manifest arguments did not " \ "raise a parse error" % opt) # manifest first args = self.full_args args.extend(['--manifest', self.manifest, opt, value]) raised = False try: easyprof.parse_args(args, InterceptingOptionParser()) except InterceptedError: raised = True self.assertTrue(raised, msg="%s and manifest arguments did not " \ "raise a parse error" % opt) def test_manifest_conflicts_profilename(self): '''Test manifest arg conflicts with profile_name arg''' self._manifest_conflicts("--profile-name", "simple-app") def test_manifest_conflicts_copyright(self): '''Test manifest arg conflicts with copyright arg''' self._manifest_conflicts("--copyright", "2013-01-01") def test_manifest_conflicts_author(self): '''Test manifest arg conflicts with author arg''' self._manifest_conflicts("--author", "Foo Bar") def test_manifest_conflicts_comment(self): '''Test manifest arg conflicts with comment arg''' self._manifest_conflicts("--comment", "some comment") def test_manifest_conflicts_abstractions(self): '''Test manifest arg conflicts with abstractions arg''' self._manifest_conflicts("--abstractions", "base") def test_manifest_conflicts_read_path(self): '''Test manifest arg conflicts with read-path arg''' self._manifest_conflicts("--read-path", "/etc/passwd") def test_manifest_conflicts_write_path(self): '''Test manifest arg conflicts with write-path arg''' self._manifest_conflicts("--write-path", "/tmp/foo") def test_manifest_conflicts_policy_groups(self): '''Test manifest arg conflicts with policy-groups arg''' self._manifest_conflicts("--policy-groups", "opt-application") def test_manifest_conflicts_name(self): '''Test manifest arg conflicts with name arg''' self._manifest_conflicts("--name", "foo") def test_manifest_conflicts_template_var(self): '''Test manifest arg conflicts with template-var arg''' self._manifest_conflicts("--template-var", "foo") def test_manifest_conflicts_policy_version(self): '''Test manifest arg conflicts with policy-version arg''' self._manifest_conflicts("--policy-version", "1.0") def test_manifest_conflicts_policy_vendor(self): '''Test manifest arg conflicts with policy-vendor arg''' self._manifest_conflicts("--policy-vendor", "somevendor") # # Test genpolicy # def _gen_policy(self, name=None, template=None, extra_args=[]): '''Generate a policy''' # Build up our args args = self.full_args if template == None: args.append('--template=%s' % self.test_template) else: args.append('--template=%s' % template) if name != None: args.append('--name=%s' % name) if len(extra_args) > 0: args += extra_args args.append(self.binary) # Now parse our args (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(self.binary, self.options) params = easyprof.gen_policy_params(self.binary, self.options) p = easyp.gen_policy(**params) # We always need to check for these search_terms = [self.binary] if name != None: search_terms.append(name) if template == None: search_terms.append(self.test_template) for s in search_terms: self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) # ###NAME### should be replaced with self.binary or 'name'. Check for that inv_s = '###NAME###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) if debugging: sys.stdout.write("%s\n" % p) return p def _gen_manifest_policy(self, manifest, use_security_prefix=True): # Build up our args args = self.full_args args.append("--manifest=/dev/null") (self.options, self.args) = easyprof.parse_args(args) (binary, self.options) = easyprof.parse_manifest(manifest.emit_json(use_security_prefix), self.options)[0] easyp = easyprof.AppArmorEasyProfile(binary, self.options) params = easyprof.gen_policy_params(binary, self.options) p = easyp.gen_policy(**params) # ###NAME### should be replaced with self.binary or 'name'. Check for that inv_s = '###NAME###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) if debugging: sys.stdout.write("%s\n" % p) return p def test__is_safe(self): '''Test _is_safe()''' bad = [ "/../../../../etc/passwd", "abstraction with spaces", "semicolon;bad", "bad\x00baz", "foo/bar", "foo'bar", 'foo"bar', ] for s in bad: self.assertFalse(easyprof._is_safe(s), "'%s' should be bad" %s) def test_genpolicy_templates_abspath(self): '''Test genpolicy (abspath to template)''' # create a new template template = os.path.join(self.tmpdir, "test-abspath-template") shutil.copy(os.path.join(self.tmpdir, 'templates', self.test_template), template) contents = open(template).read() test_string = "#teststring" open(template, 'w').write(contents + "\n%s\n" % test_string) p = self._gen_policy(template=template) for s in [self.test_template, test_string]: self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) def test_genpolicy_templates_system(self): '''Test genpolicy (system template)''' self._gen_policy() def test_genpolicy_templates_nonexistent(self): '''Test genpolicy (nonexistent template)''' try: self._gen_policy(template=os.path.join(self.tmpdir, "/nonexistent")) except easyprof.AppArmorException: return except Exception: raise raise Exception ("template should be invalid") def test_genpolicy_name(self): '''Test genpolicy (name)''' self._gen_policy(name='test-foo') def test_genpolicy_comment(self): '''Test genpolicy (comment)''' s = "test comment" p = self._gen_policy(extra_args=['--comment=%s' % s]) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) inv_s = '###COMMENT###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_author(self): '''Test genpolicy (author)''' s = "Archibald Poindexter" p = self._gen_policy(extra_args=['--author=%s' % s]) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) inv_s = '###AUTHOR###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_copyright(self): '''Test genpolicy (copyright)''' s = "2112/01/01" p = self._gen_policy(extra_args=['--copyright=%s' % s]) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) inv_s = '###COPYRIGHT###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_abstractions(self): '''Test genpolicy (single abstraction)''' s = "nameservice" p = self._gen_policy(extra_args=['--abstractions=%s' % s]) search = "#include " % s self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###ABSTRACTIONS###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_abstractions_multiple(self): '''Test genpolicy (multiple abstractions)''' abstractions = "authentication,X,user-tmp" p = self._gen_policy(extra_args=['--abstractions=%s' % abstractions]) for s in abstractions.split(','): search = "#include " % s self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###ABSTRACTIONS###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_abstractions_bad(self): '''Test genpolicy (abstractions - bad values)''' bad = [ "nonexistent", "/../../../../etc/passwd", "abstraction with spaces", ] for s in bad: try: self._gen_policy(extra_args=['--abstractions=%s' % s]) except easyprof.AppArmorException: continue except Exception: raise raise Exception ("abstraction '%s' should be invalid" % s) def _create_tmp_base_dir(self, prefix='', abstractions=[], tunables=[]): '''Create a temporary base dir layout''' base_name = 'apparmor.d' if prefix: base_name = '%s-%s' % (prefix, base_name) base_dir = os.path.join(self.tmpdir, base_name) abstractions_dir = os.path.join(base_dir, 'abstractions') tunables_dir = os.path.join(base_dir, 'tunables') os.mkdir(base_dir) os.mkdir(abstractions_dir) os.mkdir(tunables_dir) for f in abstractions: contents = ''' # Abstraction file for testing /%s r, ''' % (f) open(os.path.join(abstractions_dir, f), 'w').write(contents) for f in tunables: contents = ''' # Tunable file for testing @{AA_TEST_%s}=foo ''' % (f) open(os.path.join(tunables_dir, f), 'w').write(contents) return base_dir def test_genpolicy_abstractions_custom_base(self): '''Test genpolicy (custom base dir)''' abstraction = "custom-base-dir-test-abstraction" # The default template #includes the base abstraction and global # tunable so we need to create placeholders base = self._create_tmp_base_dir(abstractions=['base', abstraction], tunables=['global']) args = ['--abstractions=%s' % abstraction, '--base=%s' % base] p = self._gen_policy(extra_args=args) search = "#include " % abstraction self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###ABSTRACTIONS###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_abstractions_custom_base_bad(self): '''Test genpolicy (custom base dir - bad base dirs)''' abstraction = "custom-base-dir-test-abstraction" bad = [ None, '/etc/apparmor.d', '/' ] for base in bad: try: args = ['--abstractions=%s' % abstraction] if base: args.append('--base=%s' % base) self._gen_policy(extra_args=args) except easyprof.AppArmorException: continue except Exception: raise raise Exception ("abstraction '%s' should be invalid" % abstraction) def test_genpolicy_abstractions_custom_include(self): '''Test genpolicy (custom include dir)''' abstraction = "custom-include-dir-test-abstraction" # No need to create placeholders for the base abstraction or global # tunable since we're not adjusting the base directory include = self._create_tmp_base_dir(abstractions=[abstraction]) args = ['--abstractions=%s' % abstraction, '--Include=%s' % include] p = self._gen_policy(extra_args=args) search = "#include " % abstraction self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###ABSTRACTIONS###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_abstractions_custom_include_bad(self): '''Test genpolicy (custom include dir - bad include dirs)''' abstraction = "custom-include-dir-test-abstraction" bad = [ None, '/etc/apparmor.d', '/' ] for include in bad: try: args = ['--abstractions=%s' % abstraction] if include: args.append('--Include=%s' % include) self._gen_policy(extra_args=args) except easyprof.AppArmorException: continue except Exception: raise raise Exception ("abstraction '%s' should be invalid" % abstraction) def test_genpolicy_profile_name_bad(self): '''Test genpolicy (profile name - bad values)''' bad = [ "/../../../../etc/passwd", "../../../../etc/passwd", "profile name with spaces", ] for s in bad: try: self._gen_policy(extra_args=['--profile-name=%s' % s]) except easyprof.AppArmorException: continue except Exception: raise raise Exception ("profile_name '%s' should be invalid" % s) def test_genpolicy_policy_group_bad(self): '''Test genpolicy (policy group - bad values)''' bad = [ "/../../../../etc/passwd", "../../../../etc/passwd", "profile name with spaces", ] for s in bad: try: self._gen_policy(extra_args=['--policy-groups=%s' % s]) except easyprof.AppArmorException: continue except Exception: raise raise Exception ("policy group '%s' should be invalid" % s) def test_genpolicy_policygroups(self): '''Test genpolicy (single policygroup)''' groups = self.test_policygroup p = self._gen_policy(extra_args=['--policy-groups=%s' % groups]) for s in ['#include ', '#include ']: self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) inv_s = '###POLICYGROUPS###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_policygroups_multiple(self): '''Test genpolicy (multiple policygroups)''' test_policygroup2 = "test-policygroup2" contents = ''' # %s #include #include ''' % (self.test_policygroup) open(os.path.join(self.tmpdir, 'policygroups', test_policygroup2), 'w').write(contents) groups = "%s,%s" % (self.test_policygroup, test_policygroup2) p = self._gen_policy(extra_args=['--policy-groups=%s' % groups]) for s in ['#include ', '#include ', '#include ', '#include ']: self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) inv_s = '###POLICYGROUPS###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_policygroups_nonexistent(self): '''Test genpolicy (nonexistent policygroup)''' try: self._gen_policy(extra_args=['--policy-groups=nonexistent']) except easyprof.AppArmorException: return except Exception: raise raise Exception ("policygroup should be invalid") def test_genpolicy_readpath_file(self): '''Test genpolicy (read-path file)''' s = "/opt/test-foo" p = self._gen_policy(extra_args=['--read-path=%s' % s]) search = "%s rk," % s self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###READPATH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_readpath_home_file(self): '''Test genpolicy (read-path file in /home)''' s = "/home/*/test-foo" p = self._gen_policy(extra_args=['--read-path=%s' % s]) search = "owner %s rk," % s self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###READPATH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_readpath_homevar_file(self): '''Test genpolicy (read-path file in @{HOME})''' s = "@{HOME}/test-foo" p = self._gen_policy(extra_args=['--read-path=%s' % s]) search = "owner %s rk," % s self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###READPATH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_readpath_homedirs_file(self): '''Test genpolicy (read-path file in @{HOMEDIRS})''' s = "@{HOMEDIRS}/test-foo" p = self._gen_policy(extra_args=['--read-path=%s' % s]) search = "owner %s rk," % s self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###READPATH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_readpath_dir(self): '''Test genpolicy (read-path directory/)''' s = "/opt/test-foo-dir/" p = self._gen_policy(extra_args=['--read-path=%s' % s]) search_terms = ["%s rk," % s, "%s** rk," % s] for search in search_terms: self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###READPATH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_readpath_dir_glob(self): '''Test genpolicy (read-path directory/*)''' s = "/opt/test-foo-dir/*" p = self._gen_policy(extra_args=['--read-path=%s' % s]) search_terms = ["%s rk," % os.path.dirname(s), "%s rk," % s] for search in search_terms: self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###READPATH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_readpath_dir_glob_all(self): '''Test genpolicy (read-path directory/**)''' s = "/opt/test-foo-dir/**" p = self._gen_policy(extra_args=['--read-path=%s' % s]) search_terms = ["%s rk," % os.path.dirname(s), "%s rk," % s] for search in search_terms: self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###READPATH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_readpath_multiple(self): '''Test genpolicy (read-path multiple)''' paths = ["/opt/test-foo", "/home/*/test-foo", "@{HOME}/test-foo", "@{HOMEDIRS}/test-foo", "/opt/test-foo-dir/", "/opt/test-foo-dir/*", "/opt/test-foo-dir/**"] args = [] search_terms = [] for s in paths: args.append('--read-path=%s' % s) # This mimics easyprof.gen_path_rule() owner = "" if s.startswith('/home/') or s.startswith("@{HOME"): owner = "owner " if s.endswith('/'): search_terms.append("%s rk," % (s)) search_terms.append("%s%s** rk," % (owner, s)) elif s.endswith('/**') or s.endswith('/*'): search_terms.append("%s rk," % (os.path.dirname(s))) search_terms.append("%s%s rk," % (owner, s)) else: search_terms.append("%s%s rk," % (owner, s)) p = self._gen_policy(extra_args=args) for search in search_terms: self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###READPATH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_readpath_bad(self): '''Test genpolicy (read-path bad)''' s = "bar" try: self._gen_policy(extra_args=['--read-path=%s' % s]) except easyprof.AppArmorException: return except Exception: raise raise Exception ("read-path should be invalid") def test_genpolicy_writepath_file(self): '''Test genpolicy (write-path file)''' s = "/opt/test-foo" p = self._gen_policy(extra_args=['--write-path=%s' % s]) search = "%s rwk," % s self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###READPATH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_writepath_home_file(self): '''Test genpolicy (write-path file in /home)''' s = "/home/*/test-foo" p = self._gen_policy(extra_args=['--write-path=%s' % s]) search = "owner %s rwk," % s self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###READPATH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_writepath_homevar_file(self): '''Test genpolicy (write-path file in @{HOME})''' s = "@{HOME}/test-foo" p = self._gen_policy(extra_args=['--write-path=%s' % s]) search = "owner %s rwk," % s self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###READPATH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_writepath_homedirs_file(self): '''Test genpolicy (write-path file in @{HOMEDIRS})''' s = "@{HOMEDIRS}/test-foo" p = self._gen_policy(extra_args=['--write-path=%s' % s]) search = "owner %s rwk," % s self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###READPATH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_writepath_dir(self): '''Test genpolicy (write-path directory/)''' s = "/opt/test-foo-dir/" p = self._gen_policy(extra_args=['--write-path=%s' % s]) search_terms = ["%s rwk," % s, "%s** rwk," % s] for search in search_terms: self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###READPATH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_writepath_dir_glob(self): '''Test genpolicy (write-path directory/*)''' s = "/opt/test-foo-dir/*" p = self._gen_policy(extra_args=['--write-path=%s' % s]) search_terms = ["%s rwk," % os.path.dirname(s), "%s rwk," % s] for search in search_terms: self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###READPATH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_writepath_dir_glob_all(self): '''Test genpolicy (write-path directory/**)''' s = "/opt/test-foo-dir/**" p = self._gen_policy(extra_args=['--write-path=%s' % s]) search_terms = ["%s rwk," % os.path.dirname(s), "%s rwk," % s] for search in search_terms: self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###READPATH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_writepath_multiple(self): '''Test genpolicy (write-path multiple)''' paths = ["/opt/test-foo", "/home/*/test-foo", "@{HOME}/test-foo", "@{HOMEDIRS}/test-foo", "/opt/test-foo-dir/", "/opt/test-foo-dir/*", "/opt/test-foo-dir/**"] args = [] search_terms = [] for s in paths: args.append('--write-path=%s' % s) # This mimics easyprof.gen_path_rule() owner = "" if s.startswith('/home/') or s.startswith("@{HOME"): owner = "owner " if s.endswith('/'): search_terms.append("%s rwk," % (s)) search_terms.append("%s%s** rwk," % (owner, s)) elif s.endswith('/**') or s.endswith('/*'): search_terms.append("%s rwk," % (os.path.dirname(s))) search_terms.append("%s%s rwk," % (owner, s)) else: search_terms.append("%s%s rwk," % (owner, s)) p = self._gen_policy(extra_args=args) for search in search_terms: self.assertTrue(search in p, "Could not find '%s' in:\n%s" % (search, p)) inv_s = '###READPATH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_writepath_bad(self): '''Test genpolicy (write-path bad)''' s = "bar" try: self._gen_policy(extra_args=['--write-path=%s' % s]) except easyprof.AppArmorException: return except Exception: raise raise Exception ("write-path should be invalid") def test_genpolicy_templatevar(self): '''Test genpolicy (template-var single)''' s = "@{FOO}=bar" p = self._gen_policy(extra_args=['--template-var=%s' % s]) k, v = s.split('=') s = '%s="%s"' % (k, v) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) inv_s = '###TEMPLATEVAR###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_templatevar_multiple(self): '''Test genpolicy (template-var multiple)''' variables = ['@{FOO}=bar', '@{BAR}=baz'] args = [] for s in variables: args.append('--template-var=%s' % s) p = self._gen_policy(extra_args=args) for s in variables: k, v = s.split('=') s = '%s="%s"' % (k, v) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) inv_s = '###TEMPLATEVAR###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_templatevar_bad(self): '''Test genpolicy (template-var - bad values)''' bad = [ "{FOO}=bar", "@FOO}=bar", "@{FOO=bar", "FOO=bar", "@FOO=bar", "@{FOO}=/../../../etc/passwd", "@{FOO}=bar=foo", "@{FOO;BAZ}=bar", '@{FOO}=bar"baz', ] for s in bad: try: self._gen_policy(extra_args=['--template-var=%s' % s]) except easyprof.AppArmorException: continue except Exception: raise raise Exception ("template-var should be invalid") def test_genpolicy_invalid_template_policy(self): '''Test genpolicy (invalid template policy)''' # create a new template template = os.path.join(self.tmpdir, "test-invalid-template") shutil.copy(os.path.join(self.tmpdir, 'templates', self.test_template), template) contents = open(template).read() bad_pol = "" bad_string = "bzzzt" for line in contents.splitlines(): if '}' in line: bad_pol += bad_string else: bad_pol += line bad_pol += "\n" open(template, 'w').write(bad_pol) try: self._gen_policy(template=template) except easyprof.AppArmorException: return except Exception: raise raise Exception ("policy should be invalid") def test_genpolicy_no_binary_without_profile_name(self): '''Test genpolicy (no binary with no profile name)''' try: easyprof.gen_policy_params(None, self.options) except easyprof.AppArmorException: return except Exception: raise raise Exception ("No binary or profile name should have been invalid") def test_genpolicy_with_binary_with_profile_name(self): '''Test genpolicy (binary with profile name)''' profile_name = "some-profile-name" p = self._gen_policy(extra_args=['--profile-name=%s' % profile_name]) s = 'profile "%s" "%s" {' % (profile_name, self.binary) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) inv_s = '###PROFILEATTACH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_with_binary_without_profile_name(self): '''Test genpolicy (binary without profile name)''' p = self._gen_policy() s = '"%s" {' % (self.binary) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) inv_s = '###PROFILEATTACH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_genpolicy_without_binary_with_profile_name(self): '''Test genpolicy (no binary with profile name)''' profile_name = "some-profile-name" args = self.full_args args.append('--profile-name=%s' % profile_name) (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(None, self.options) params = easyprof.gen_policy_params(None, self.options) p = easyp.gen_policy(**params) s = 'profile "%s" {' % (profile_name) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) inv_s = '###PROFILEATTACH###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) # manifest tests def test_gen_manifest_policy_with_binary_with_profile_name(self): '''Test gen_manifest_policy (binary with profile name)''' m = Manifest("test_gen_manifest_policy") m.add_binary(self.ls) self._gen_manifest_policy(m) def test_gen_manifest_policy_without_binary_with_profile_name(self): '''Test gen_manifest_policy (no binary with profile name)''' m = Manifest("test_gen_manifest_policy") self._gen_manifest_policy(m) def test_gen_manifest_policy_templates_system(self): '''Test gen_manifest_policy (system template)''' m = Manifest("test_gen_manifest_policy") m.add_template(self.test_template) self._gen_manifest_policy(m) def test_gen_manifest_policy_templates_system_noprefix(self): '''Test gen_manifest_policy (system template, no security prefix)''' m = Manifest("test_gen_manifest_policy") m.add_template(self.test_template) self._gen_manifest_policy(m, use_security_prefix=False) def test_gen_manifest_abs_path_template(self): '''Test gen_manifest_policy (abs path template)''' m = Manifest("test_gen_manifest_policy") m.add_template("/etc/shadow") try: self._gen_manifest_policy(m) except easyprof.AppArmorException: return except Exception: raise raise Exception ("abs path template name should be invalid") def test_gen_manifest_escape_path_templates(self): '''Test gen_manifest_policy (esc path template)''' m = Manifest("test_gen_manifest_policy") m.add_template("../../../../../../../../etc/shadow") try: self._gen_manifest_policy(m) except easyprof.AppArmorException: return except Exception: raise raise Exception ("../ template name should be invalid") def test_gen_manifest_policy_templates_nonexistent(self): '''Test gen manifest policy (nonexistent template)''' m = Manifest("test_gen_manifest_policy") m.add_template("nonexistent") try: self._gen_manifest_policy(m) except easyprof.AppArmorException: return except Exception: raise raise Exception ("template should be invalid") def test_gen_manifest_policy_comment(self): '''Test gen manifest policy (comment)''' s = "test comment" m = Manifest("test_gen_manifest_policy") m.add_comment(s) p = self._gen_manifest_policy(m) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) inv_s = '###COMMENT###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_gen_manifest_policy_author(self): '''Test gen manifest policy (author)''' s = "Archibald Poindexter" m = Manifest("test_gen_manifest_policy") m.add_author(s) p = self._gen_manifest_policy(m) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) inv_s = '###AUTHOR###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_gen_manifest_policy_copyright(self): '''Test genpolicy (copyright)''' s = "2112/01/01" m = Manifest("test_gen_manifest_policy") m.add_copyright(s) p = self._gen_manifest_policy(m) self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) inv_s = '###COPYRIGHT###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_gen_manifest_policy_policygroups(self): '''Test gen manifest policy (single policygroup)''' groups = self.test_policygroup m = Manifest("test_gen_manifest_policy") m.add_policygroups(groups) p = self._gen_manifest_policy(m) for s in ['#include ', '#include ']: self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) inv_s = '###POLICYGROUPS###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_gen_manifest_policy_policygroups_multiple(self): '''Test genpolicy (multiple policygroups)''' test_policygroup2 = "test-policygroup2" contents = ''' # %s #include #include ''' % (self.test_policygroup) open(os.path.join(self.tmpdir, 'policygroups', test_policygroup2), 'w').write(contents) groups = "%s,%s" % (self.test_policygroup, test_policygroup2) m = Manifest("test_gen_manifest_policy") m.add_policygroups(groups) p = self._gen_manifest_policy(m) for s in ['#include ', '#include ', '#include ', '#include ']: self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) inv_s = '###POLICYGROUPS###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_gen_manifest_policy_policygroups_nonexistent(self): '''Test gen manifest policy (nonexistent policygroup)''' groups = "nonexistent" m = Manifest("test_gen_manifest_policy") m.add_policygroups(groups) try: self._gen_manifest_policy(m) except easyprof.AppArmorException: return except Exception: raise raise Exception ("policygroup should be invalid") def test_gen_manifest_policy_templatevar(self): '''Test gen manifest policy (template-var single)''' m = Manifest("test_gen_manifest_policy") m.add_template_variable("FOO", "bar") p = self._gen_manifest_policy(m) s = '@{FOO}="bar"' self.assertTrue(s in p, "Could not find '%s' in:\n%s" % (s, p)) inv_s = '###TEMPLATEVAR###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_gen_manifest_policy_templatevar_multiple(self): '''Test gen manifest policy (template-var multiple)''' variables = [["FOO", "bar"], ["BAR", "baz"]] m = Manifest("test_gen_manifest_policy") for s in variables: m.add_template_variable(s[0], s[1]) p = self._gen_manifest_policy(m) for s in variables: str_s = '@{%s}="%s"' % (s[0], s[1]) self.assertTrue(str_s in p, "Could not find '%s' in:\n%s" % (str_s, p)) inv_s = '###TEMPLATEVAR###' self.assertFalse(inv_s in p, "Found '%s' in :\n%s" % (inv_s, p)) def test_gen_manifest_policy_invalid_keys(self): '''Test gen manifest policy (invalid keys)''' keys = ['config_file', 'debug', 'help', 'list-templates', 'list_templates', 'show-template', 'show_template', 'list-policy-groups', 'list_policy_groups', 'show-policy-group', 'show_policy_group', 'templates-dir', 'templates_dir', 'policy-groups-dir', 'policy_groups_dir', 'nonexistent', 'no_verify', ] args = self.full_args args.append("--manifest=/dev/null") (self.options, self.args) = easyprof.parse_args(args) for k in keys: security = dict() security["profile_name"] = "test-app" security[k] = "bad" j = json.dumps(security, indent=2) try: easyprof.parse_manifest(j, self.options) except easyprof.AppArmorException: continue raise Exception ("'%s' should be invalid" % k) def test_gen_manifest(self): '''Test gen_manifest''' # this should come from manpage m = '''{ "security": { "profiles": { "com.example.foo": { "abstractions": [ "audio", "gnome" ], "author": "Your Name", "binary": "/opt/foo/**", "comment": "Unstructured single-line comment", "copyright": "Unstructured single-line copyright statement", "name": "My Foo App", "policy_groups": [ "opt-application", "user-application" ], "policy_vendor": "somevendor", "policy_version": 1.0, "read_path": [ "/tmp/foo_r", "/tmp/bar_r/" ], "template": "user-application", "template_variables": { "APPNAME": "foo", "VAR1": "bar", "VAR2": "baz" }, "write_path": [ "/tmp/foo_w", "/tmp/bar_w/" ] } } } }''' for d in ['policygroups', 'templates']: shutil.copytree(os.path.join(self.tmpdir, d), os.path.join(self.tmpdir, d, "somevendor/1.0")) args = self.full_args args.append("--manifest=/dev/null") (self.options, self.args) = easyprof.parse_args(args) (binary, self.options) = easyprof.parse_manifest(m, self.options)[0] easyp = easyprof.AppArmorEasyProfile(binary, self.options) params = easyprof.gen_policy_params(binary, self.options) # verify we get the same manifest back man_new = easyp.gen_manifest(params) self.assertEquals(m, man_new) def test_gen_manifest_ubuntu(self): '''Test gen_manifest (ubuntu)''' # this should be based on the manpage (but use existing policy_groups # and template m = '''{ "security": { "profiles": { "com.ubuntu.developer.myusername.MyCoolApp": { "name": "MyCoolApp", "policy_groups": [ "opt-application", "user-application" ], "policy_vendor": "ubuntu", "policy_version": 1.0, "template": "user-application", "template_variables": { "APPNAME": "MyCoolApp", "APPVERSION": "0.1.2" } } } } }''' for d in ['policygroups', 'templates']: shutil.copytree(os.path.join(self.tmpdir, d), os.path.join(self.tmpdir, d, "ubuntu/1.0")) args = self.full_args args.append("--manifest=/dev/null") (self.options, self.args) = easyprof.parse_args(args) (binary, self.options) = easyprof.parse_manifest(m, self.options)[0] easyp = easyprof.AppArmorEasyProfile(binary, self.options) params = easyprof.gen_policy_params(binary, self.options) # verify we get the same manifest back man_new = easyp.gen_manifest(params) self.assertEquals(m, man_new) def test_parse_manifest_no_version(self): '''Test parse_manifest (vendor with no version)''' # this should come from manpage m = '''{ "security": { "profiles": { "com.ubuntu.developer.myusername.MyCoolApp": { "policy_groups": [ "opt-application", "user-application" ], "policy_vendor": "ubuntu", "template": "user-application", "template_variables": { "APPNAME": "MyCoolApp", "APPVERSION": "0.1.2" } } } } }''' args = self.full_args args.append("--manifest=/dev/null") (self.options, self.args) = easyprof.parse_args(args) (binary, self.options) = easyprof.parse_manifest(m, self.options)[0] try: easyprof.AppArmorEasyProfile(binary, self.options) except easyprof.AppArmorException: return raise Exception ("Should have failed on missing version") def test_parse_manifest_no_vendor(self): '''Test parse_manifest (version with no vendor)''' # this should come from manpage m = '''{ "security": { "profiles": { "com.ubuntu.developer.myusername.MyCoolApp": { "policy_groups": [ "opt-application", "user-application" ], "policy_version": 1.0, "template": "user-application", "template_variables": { "APPNAME": "MyCoolApp", "APPVERSION": "0.1.2" } } } } }''' args = self.full_args args.append("--manifest=/dev/null") (self.options, self.args) = easyprof.parse_args(args) (binary, self.options) = easyprof.parse_manifest(m, self.options)[0] try: easyprof.AppArmorEasyProfile(binary, self.options) except easyprof.AppArmorException: return raise Exception ("Should have failed on missing vendor") def test_parse_manifest_multiple(self): '''Test parse_manifest_multiple''' m = '''{ "security": { "profiles": { "com.example.foo": { "abstractions": [ "audio", "gnome" ], "author": "Your Name", "binary": "/opt/foo/**", "comment": "Unstructured single-line comment", "copyright": "Unstructured single-line copyright statement", "name": "My Foo App", "policy_groups": [ "opt-application", "user-application" ], "read_path": [ "/tmp/foo_r", "/tmp/bar_r/" ], "template": "user-application", "template_variables": { "APPNAME": "foo", "VAR1": "bar", "VAR2": "baz" }, "write_path": [ "/tmp/foo_w", "/tmp/bar_w/" ] }, "com.ubuntu.developer.myusername.MyCoolApp": { "policy_groups": [ "opt-application" ], "policy_vendor": "ubuntu", "policy_version": 1.0, "template": "user-application", "template_variables": { "APPNAME": "MyCoolApp", "APPVERSION": "0.1.2" } } } } }''' for d in ['policygroups', 'templates']: shutil.copytree(os.path.join(self.tmpdir, d), os.path.join(self.tmpdir, d, "ubuntu/1.0")) args = self.full_args args.append("--manifest=/dev/null") (self.options, self.args) = easyprof.parse_args(args) profiles = easyprof.parse_manifest(m, self.options) for (binary, options) in profiles: easyp = easyprof.AppArmorEasyProfile(binary, options) params = easyprof.gen_policy_params(binary, options) easyp.gen_manifest(params) easyp.gen_policy(**params) # verify manifest tests def _verify_manifest(self, m, expected, invalid=False): args = self.full_args args.append("--manifest=/dev/null") (self.options, self.args) = easyprof.parse_args(args) try: (binary, options) = easyprof.parse_manifest(m, self.options)[0] except easyprof.AppArmorException: if invalid: return raise params = easyprof.gen_policy_params(binary, options) if expected: self.assertTrue(easyprof.verify_manifest(params, args), "params=%s\nmanifest=%s" % (params,m)) else: self.assertFalse(easyprof.verify_manifest(params, args), "params=%s\nmanifest=%s" % (params,m)) def test_verify_manifest_full(self): '''Test verify_manifest (full)''' m = '''{ "security": { "profiles": { "com.example.foo": { "abstractions": [ "base" ], "author": "Your Name", "binary": "/opt/com.example/foo/**", "comment": "some free-form single-line comment", "copyright": "Unstructured single-line copyright statement", "name": "foo", "policy_groups": [ "user-application", "opt-application" ], "template": "user-application", "template_variables": { "OK1": "foo", "OK2": "com.example.foo" } } } } }''' self._verify_manifest(m, expected=True) def test_verify_manifest_full_bad(self): '''Test verify_manifest (full bad)''' m = '''{ "security": { "profiles": { "/com.example.foo": { "abstractions": [ "audio", "gnome" ], "author": "Your Name", "binary": "/usr/foo/**", "comment": "some free-form single-line comment", "copyright": "Unstructured single-line copyright statement", "name": "foo", "policy_groups": [ "user-application", "opt-application" ], "read_path": [ "/tmp/foo_r", "/tmp/bar_r/" ], "template": "user-application", "template_variables": { "VAR1": "f*o", "VAR2": "*foo", "VAR3": "fo*", "VAR4": "b{ar", "VAR5": "b{a,r}", "VAR6": "b}ar", "VAR7": "bar[0-9]", "VAR8": "b{ar", "VAR9": "/tmp/../etc/passwd" }, "write_path": [ "/tmp/foo_w", "/tmp/bar_w/" ] } } } }''' self._verify_manifest(m, expected=False, invalid=True) def test_verify_manifest_binary(self): '''Test verify_manifest (binary in /usr)''' m = '''{ "security": { "profiles": { "com.example.foo": { "binary": "/usr/foo/**", "template": "user-application" } } } }''' self._verify_manifest(m, expected=True) def test_verify_manifest_profile_profile_name_bad(self): '''Test verify_manifest (bad profile_name)''' m = '''{ "security": { "profiles": { "/foo": { "binary": "/opt/com.example/foo/**", "template": "user-application" } } } }''' self._verify_manifest(m, expected=False, invalid=True) m = '''{ "security": { "profiles": { "bin/*": { "binary": "/opt/com.example/foo/**", "template": "user-application" } } } }''' self._verify_manifest(m, expected=False) def test_verify_manifest_profile_profile_name(self): '''Test verify_manifest (profile_name)''' m = '''{ "security": { "profiles": { "com.example.foo": { "binary": "/opt/com.example/foo/**", "template": "user-application" } } } }''' self._verify_manifest(m, expected=True) def test_verify_manifest_profile_abstractions(self): '''Test verify_manifest (abstractions)''' m = '''{ "security": { "profiles": { "com.example.foo": { "binary": "/opt/com.example/foo/**", "template": "user-application", "abstractions": [ "base" ] } } } }''' self._verify_manifest(m, expected=True) def test_verify_manifest_profile_abstractions_bad(self): '''Test verify_manifest (bad abstractions)''' m = '''{ "security": { "profiles": { "com.example.foo": { "binary": "/opt/com.example/foo/**", "template": "user-application", "abstractions": [ "user-tmp" ] } } } }''' self._verify_manifest(m, expected=False) def test_verify_manifest_profile_template_var(self): '''Test verify_manifest (good template_var)''' m = '''{ "security": { "profiles": { "com.example.foo": { "binary": "/opt/com.example/something with spaces/**", "template": "user-application", "template_variables": { "OK1": "foo", "OK2": "com.example.foo", "OK3": "something with spaces" } } } } }''' self._verify_manifest(m, expected=True) def test_verify_manifest_profile_template_var_bad(self): '''Test verify_manifest (bad template_var)''' for v in ['"VAR1": "f*o"', '"VAR2": "*foo"', '"VAR3": "fo*"', '"VAR4": "b{ar"', '"VAR5": "b{a,r}"', '"VAR6": "b}ar"', '"VAR7": "bar[0-9]"', '"VAR8": "b{ar"', '"VAR9": "foo/bar"' # this is valid, but potentially unsafe ]: m = '''{ "security": { "profiles": { "com.example.foo": { "binary": "/opt/com.example/foo/**", "template": "user-application", "template_variables": { %s } } } } }''' % v self._verify_manifest(m, expected=False) def test_manifest_invalid(self): '''Test invalid manifest (parse error)''' m = '''{ "security": { "com.example.foo": { "binary": "/opt/com.example/foo/**", "template": "user-application", "abstractions": [ "base" ] }''' self._verify_manifest(m, expected=False, invalid=True) def test_manifest_invalid2(self): '''Test invalid manifest (profile_name is not key)''' m = '''{ "security": { "binary": "/opt/com.example/foo/**", "template": "user-application", "abstractions": [ "base" ] } }''' self._verify_manifest(m, expected=False, invalid=True) def test_manifest_invalid3(self): '''Test invalid manifest (profile_name in dict)''' m = '''{ "security": { "binary": "/opt/com.example/foo/**", "template": "user-application", "abstractions": [ "base" ], "profile_name": "com.example.foo" } }''' self._verify_manifest(m, expected=False, invalid=True) def test_manifest_invalid4(self): '''Test invalid manifest (bad path in template var)''' for v in ['"VAR1": "/tmp/../etc/passwd"', '"VAR2": "./"', '"VAR3": "foo\"bar"', '"VAR4": "foo//bar"', ]: m = '''{ "security": { "profiles": { "com.example.foo": { "binary": "/opt/com.example/foo/**", "template": "user-application", "template_variables": { %s } } } } }''' % v args = self.full_args args.append("--manifest=/dev/null") (self.options, self.args) = easyprof.parse_args(args) (binary, options) = easyprof.parse_manifest(m, self.options)[0] params = easyprof.gen_policy_params(binary, options) try: easyprof.verify_manifest(params) except easyprof.AppArmorException: return raise Exception ("Should have failed with invalid variable declaration") # policy version tests def test_policy_vendor_manifest_nonexistent(self): '''Test policy vendor via manifest (nonexistent)''' m = '''{ "security": { "profiles": { "com.example.foo": { "policy_vendor": "nonexistent", "policy_version": 1.0, "binary": "/opt/com.example/foo/**", "template": "user-application" } } } }''' # Build up our args args = self.full_args args.append("--manifest=/dev/null") (self.options, self.args) = easyprof.parse_args(args) (binary, self.options) = easyprof.parse_manifest(m, self.options)[0] try: easyprof.AppArmorEasyProfile(binary, self.options) except easyprof.AppArmorException: return raise Exception ("Should have failed with non-existent directory") def test_policy_version_manifest(self): '''Test policy version via manifest (good)''' policy_vendor = "somevendor" policy_version = "1.0" policy_subdir = "%s/%s" % (policy_vendor, policy_version) m = '''{ "security": { "profiles": { "com.example.foo": { "policy_vendor": "%s", "policy_version": %s, "binary": "/opt/com.example/foo/**", "template": "user-application" } } } }''' % (policy_vendor, policy_version) for d in ['policygroups', 'templates']: shutil.copytree(os.path.join(self.tmpdir, d), os.path.join(self.tmpdir, d, policy_subdir)) # Build up our args args = self.full_args args.append("--manifest=/dev/null") (self.options, self.args) = easyprof.parse_args(args) (binary, self.options) = easyprof.parse_manifest(m, self.options)[0] easyp = easyprof.AppArmorEasyProfile(binary, self.options) tdir = os.path.join(self.tmpdir, 'templates', policy_subdir) for t in easyp.get_templates(): self.assertTrue(t.startswith(tdir)) pdir = os.path.join(self.tmpdir, 'policygroups', policy_subdir) for p in easyp.get_policy_groups(): self.assertTrue(p.startswith(pdir)) params = easyprof.gen_policy_params(binary, self.options) easyp.gen_policy(**params) def test_policy_vendor_version_args(self): '''Test policy vendor and version via command line args (good)''' policy_version = "1.0" policy_vendor = "somevendor" policy_subdir = "%s/%s" % (policy_vendor, policy_version) # Create the directories for d in ['policygroups', 'templates']: shutil.copytree(os.path.join(self.tmpdir, d), os.path.join(self.tmpdir, d, policy_subdir)) # Build up our args args = self.full_args args.append("--policy-version=%s" % policy_version) args.append("--policy-vendor=%s" % policy_vendor) (self.options, self.args) = easyprof.parse_args(args) (self.options, self.args) = easyprof.parse_args(self.full_args + [self.binary]) easyp = easyprof.AppArmorEasyProfile(self.binary, self.options) tdir = os.path.join(self.tmpdir, 'templates', policy_subdir) for t in easyp.get_templates(): self.assertTrue(t.startswith(tdir), \ "'%s' does not start with '%s'" % (t, tdir)) pdir = os.path.join(self.tmpdir, 'policygroups', policy_subdir) for p in easyp.get_policy_groups(): self.assertTrue(p.startswith(pdir), \ "'%s' does not start with '%s'" % (p, pdir)) params = easyprof.gen_policy_params(self.binary, self.options) easyp.gen_policy(**params) def test_policy_vendor_args_nonexistent(self): '''Test policy vendor via command line args (nonexistent)''' policy_vendor = "nonexistent" policy_version = "1.0" args = self.full_args args.append("--policy-version=%s" % policy_version) args.append("--policy-vendor=%s" % policy_vendor) (self.options, self.args) = easyprof.parse_args(args) (self.options, self.args) = easyprof.parse_args(self.full_args + [self.binary]) try: easyprof.AppArmorEasyProfile(self.binary, self.options) except easyprof.AppArmorException: return raise Exception ("Should have failed with non-existent directory") def test_policy_version_args_bad(self): '''Test policy version via command line args (bad)''' bad = [ "../../../../../../etc", "notanumber", "v1.0a", "-1", ] for policy_version in bad: args = self.full_args args.append("--policy-version=%s" % policy_version) args.append("--policy-vendor=somevendor") (self.options, self.args) = easyprof.parse_args(args) (self.options, self.args) = easyprof.parse_args(self.full_args + [self.binary]) try: easyprof.AppArmorEasyProfile(self.binary, self.options) except easyprof.AppArmorException: continue raise Exception ("Should have failed with bad version") def test_policy_vendor_args_bad(self): '''Test policy vendor via command line args (bad)''' bad = [ "../../../../../../etc", "vendor with space", "semicolon;isbad", ] for policy_vendor in bad: args = self.full_args args.append("--policy-vendor=%s" % policy_vendor) args.append("--policy-version=1.0") (self.options, self.args) = easyprof.parse_args(args) (self.options, self.args) = easyprof.parse_args(self.full_args + [self.binary]) try: easyprof.AppArmorEasyProfile(self.binary, self.options) except easyprof.AppArmorException: continue raise Exception ("Should have failed with bad vendor") # output_directory tests def test_output_directory_multiple(self): '''Test output_directory (multiple)''' files = dict() files["com.example.foo"] = "com.example.foo" files["com.ubuntu.developer.myusername.MyCoolApp"] = "com.ubuntu.developer.myusername.MyCoolApp" files["usr.bin.baz"] = "/usr/bin/baz" m = '''{ "security": { "profiles": { "%s": { "abstractions": [ "audio", "gnome" ], "author": "Your Name", "binary": "/opt/foo/**", "comment": "Unstructured single-line comment", "copyright": "Unstructured single-line copyright statement", "name": "My Foo App", "policy_groups": [ "opt-application", "user-application" ], "read_path": [ "/tmp/foo_r", "/tmp/bar_r/" ], "template": "user-application", "template_variables": { "APPNAME": "foo", "VAR1": "bar", "VAR2": "baz" }, "write_path": [ "/tmp/foo_w", "/tmp/bar_w/" ] }, "%s": { "policy_groups": [ "opt-application", "user-application" ], "template": "user-application", "template_variables": { "APPNAME": "MyCoolApp", "APPVERSION": "0.1.2" } }, "%s": { "abstractions": [ "gnome" ], "policy_groups": [ "user-application" ], "template_variables": { "APPNAME": "baz" } } } } }''' % (files["com.example.foo"], files["com.ubuntu.developer.myusername.MyCoolApp"], files["usr.bin.baz"]) out_dir = os.path.join(self.tmpdir, "output") args = self.full_args args.append("--manifest=/dev/null") (self.options, self.args) = easyprof.parse_args(args) profiles = easyprof.parse_manifest(m, self.options) for (binary, options) in profiles: easyp = easyprof.AppArmorEasyProfile(binary, options) params = easyprof.gen_policy_params(binary, options) easyp.output_policy(params, dir=out_dir) for fn in files: f = os.path.join(out_dir, fn) self.assertTrue(os.path.exists(f), "Could not find '%s'" % f) def test_output_directory_single(self): '''Test output_directory (single)''' files = dict() files["com.example.foo"] = "com.example.foo" m = '''{ "security": { "profiles": { "%s": { "abstractions": [ "audio", "gnome" ], "author": "Your Name", "binary": "/opt/foo/**", "comment": "Unstructured single-line comment", "copyright": "Unstructured single-line copyright statement", "name": "My Foo App", "policy_groups": [ "opt-application", "user-application" ], "read_path": [ "/tmp/foo_r", "/tmp/bar_r/" ], "template": "user-application", "template_variables": { "APPNAME": "foo", "VAR1": "bar", "VAR2": "baz" }, "write_path": [ "/tmp/foo_w", "/tmp/bar_w/" ] } } } }''' % (files["com.example.foo"]) out_dir = os.path.join(self.tmpdir, "output") args = self.full_args args.append("--manifest=/dev/null") (self.options, self.args) = easyprof.parse_args(args) profiles = easyprof.parse_manifest(m, self.options) for (binary, options) in profiles: easyp = easyprof.AppArmorEasyProfile(binary, options) params = easyprof.gen_policy_params(binary, options) easyp.output_policy(params, dir=out_dir) for fn in files: f = os.path.join(out_dir, fn) self.assertTrue(os.path.exists(f), "Could not find '%s'" % f) def test_output_directory_invalid(self): '''Test output_directory (output directory exists as file)''' files = dict() files["usr.bin.baz"] = "/usr/bin/baz" m = '''{ "security": { "profiles": { "%s": { "abstractions": [ "gnome" ], "policy_groups": [ "user-application" ], "template_variables": { "APPNAME": "baz" } } } } }''' % files["usr.bin.baz"] out_dir = os.path.join(self.tmpdir, "output") open(out_dir, 'w').close() args = self.full_args args.append("--manifest=/dev/null") (self.options, self.args) = easyprof.parse_args(args) (binary, options) = easyprof.parse_manifest(m, self.options)[0] easyp = easyprof.AppArmorEasyProfile(binary, options) params = easyprof.gen_policy_params(binary, options) try: easyp.output_policy(params, dir=out_dir) except easyprof.AppArmorException: return raise Exception ("Should have failed with 'is not a directory'") def test_output_directory_invalid_params(self): '''Test output_directory (no binary or profile_name)''' files = dict() files["usr.bin.baz"] = "/usr/bin/baz" m = '''{ "security": { "profiles": { "%s": { "abstractions": [ "gnome" ], "policy_groups": [ "user-application" ], "template_variables": { "APPNAME": "baz" } } } } }''' % files["usr.bin.baz"] out_dir = os.path.join(self.tmpdir, "output") args = self.full_args args.append("--manifest=/dev/null") (self.options, self.args) = easyprof.parse_args(args) (binary, options) = easyprof.parse_manifest(m, self.options)[0] easyp = easyprof.AppArmorEasyProfile(binary, options) params = easyprof.gen_policy_params(binary, options) del params['binary'] try: easyp.output_policy(params, dir=out_dir) except easyprof.AppArmorException: return raise Exception ("Should have failed with 'Must specify binary and/or profile name'") def test_output_directory_invalid2(self): '''Test output_directory (profile exists)''' files = dict() files["usr.bin.baz"] = "/usr/bin/baz" m = '''{ "security": { "profiles": { "%s": { "abstractions": [ "gnome" ], "policy_groups": [ "user-application" ], "template_variables": { "APPNAME": "baz" } } } } }''' % files["usr.bin.baz"] out_dir = os.path.join(self.tmpdir, "output") os.mkdir(out_dir) open(os.path.join(out_dir, "usr.bin.baz"), 'w').close() args = self.full_args args.append("--manifest=/dev/null") (self.options, self.args) = easyprof.parse_args(args) (binary, options) = easyprof.parse_manifest(m, self.options)[0] easyp = easyprof.AppArmorEasyProfile(binary, options) params = easyprof.gen_policy_params(binary, options) try: easyp.output_policy(params, dir=out_dir) except easyprof.AppArmorException: return raise Exception ("Should have failed with 'already exists'") def test_output_directory_args(self): '''Test output_directory (args)''' files = dict() files["usr.bin.baz"] = "/usr/bin/baz" # Build up our args args = self.full_args args.append('--template=%s' % self.test_template) args.append('--name=%s' % 'foo') args.append(files["usr.bin.baz"]) out_dir = os.path.join(self.tmpdir, "output") # Now parse our args (self.options, self.args) = easyprof.parse_args(args) easyp = easyprof.AppArmorEasyProfile(files["usr.bin.baz"], self.options) params = easyprof.gen_policy_params(files["usr.bin.baz"], self.options) easyp.output_policy(params, dir=out_dir) for fn in files: f = os.path.join(out_dir, fn) self.assertTrue(os.path.exists(f), "Could not find '%s'" % f) # # utility classes # def test_valid_profile_name(self): '''Test valid_profile_name''' names = ['foo', 'com.example.foo', '/usr/bin/foo', 'com.example.app_myapp_1:2.3+ab12~foo', ] for n in names: self.assertTrue(easyprof.valid_profile_name(n), "'%s' should be valid" % n) def test_valid_profile_name_invalid(self): '''Test valid_profile_name (invalid)''' names = ['fo/o', '/../../etc/passwd', '../../etc/passwd', './../etc/passwd', './etc/passwd', '/usr/bin//foo', '/usr/bin/./foo', 'foo`', 'foo!', 'foo@', 'foo$', 'foo#', 'foo%', 'foo^', 'foo&', 'foo*', 'foo(', 'foo)', 'foo=', 'foo{', 'foo}', 'foo[', 'foo]', 'foo|', 'foo/', 'foo\\', 'foo;', 'foo\'', 'foo"', 'foo<', 'foo>', 'foo?', 'foo\/', 'foo,', '_foo', ] for n in names: self.assertFalse(easyprof.valid_profile_name(n), "'%s' should be invalid" % n) def test_valid_path(self): '''Test valid_path''' names = ['/bin/bar', '/etc/apparmor.d/com.example.app_myapp_1:2.3+ab12~foo', ] names_rel = ['bin/bar', 'apparmor.d/com.example.app_myapp_1:2.3+ab12~foo', 'com.example.app_myapp_1:2.3+ab12~foo', ] for n in names: self.assertTrue(easyprof.valid_path(n), "'%s' should be valid" % n) for n in names_rel: self.assertTrue(easyprof.valid_path(n, relative_ok=True), "'%s' should be valid" % n) def test_zz_valid_path_invalid(self): '''Test valid_path (invalid)''' names = ['/bin//bar', 'bin/bar', '/../etc/passwd', './bin/bar', './', ] names_rel = ['bin/../bar', 'apparmor.d/../passwd', 'com.example.app_"myapp_1:2.3+ab12~foo', ] for n in names: self.assertFalse(easyprof.valid_path(n, relative_ok=False), "'%s' should be invalid" % n) for n in names_rel: self.assertFalse(easyprof.valid_path(n, relative_ok=True), "'%s' should be invalid" % n) # # End test class # # # Main # if __name__ == '__main__': absfn = os.path.abspath(sys.argv[0]) topdir = os.path.dirname(os.path.dirname(absfn)) if len(sys.argv) > 1 and (sys.argv[1] == '-d' or sys.argv[1] == '--debug'): debugging = True # run the tests suite = unittest.TestSuite() suite.addTest(unittest.TestLoader().loadTestsFromTestCase(T)) rc = unittest.TextTestRunner(verbosity=1).run(suite) if not rc.wasSuccessful(): sys.exit(1) apparmor-2.13.3/utils/test/Makefile0000644000175000017500000000737713502024172015002 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (c) 1999, 2004-2009 NOVELL (All rights reserved) # Copyright (c) 2010-2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Novell, Inc. # ---------------------------------------------------------------------- NAME = apparmor-utils all: COMMONDIR=../../common/ include $(COMMONDIR)/Make.rules ifdef USE_SYSTEM LD_LIBRARY_PATH= PYTHONPATH= CONFDIR= BASEDIR= PARSER= else # PYTHON_DIST_BUILD_PATH based on libapparmor/swig/python/test/Makefile.am PYTHON_DIST_BUILD_PATH = ../../libraries/libapparmor/swig/python/build/$$($(PYTHON) -c "import distutils.util; import platform; print(\"lib.%s-%s\" %(distutils.util.get_platform(), platform.python_version()[:3]))") LD_LIBRARY_PATH=../../libraries/libapparmor/src/.libs/ PYTHONPATH=..:$(PYTHON_DIST_BUILD_PATH) CONFDIR=$(CURDIR) BASEDIR=../../profiles/apparmor.d PARSER=../../parser/apparmor_parser endif .PHONY: __libapparmor __parser __libapparmor: ifndef USE_SYSTEM @if [ ! -f $(LD_LIBRARY_PATH)libapparmor.so ]; then \ echo "error: $(LD_LIBRARY_PATH)libapparmor.so is missing. Pick one of these possible solutions:" 1>&2; \ echo " 1) Build against the in-tree libapparmor by building it first and then trying again. See the top-level README for help." 1>&2; \ echo " 2) Build against the system libapparmor by adding USE_SYSTEM=1 to your make command." 1>&2; \ exit 1; \ fi endif __parser: ifndef USE_SYSTEM @if [ ! -f $(PARSER) ]; then \ echo "error: $(PARSER) is missing. Pick one of these possible solutions:" 1>&2; \ echo " 1) Test using the in-tree parser by building it first and then trying again. See the top-level README for help." 1>&2; \ echo " 2) Test using the system parser by adding USE_SYSTEM=1 to your make command." 1>&2; \ exit 1; \ fi endif COVERAGE_OMIT=test-*.py,common_test.py ifneq ($(COVERAGE_OUT), ) HTML_COVR_ARGS=-d $(COVERAGE_OUT) endif # use make COVERAGE_IGNORE_FAILURES=true coverage to build coverage data even if some tests fail ifeq ($(COVERAGE_IGNORE_FAILURES), true) COVERAGE_IGNORE_FAILURES_CMD=true else COVERAGE_IGNORE_FAILURES_CMD=set -e endif .PHONY: clean check coverage coverage-report coverage-html ifndef VERBOSE .SILENT: clean check .coverage coverage coverage-report coverage-html endif clean: rm -rf __pycache__/ .coverage htmlcov check: __libapparmor __parser export PYTHONPATH=$(PYTHONPATH) LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) LC_ALL=C __AA_CONFDIR=$(CONFDIR) __AA_BASEDIR=$(BASEDIR) __AA_PARSER=$(PARSER) ; $(foreach test, $(wildcard test-*.py), echo ; echo === $(test) === ; $(call pyalldo, $(test))) .coverage: $(wildcard ../aa-* ../apparmor/*.py test-*.py) __libapparmor __parser export PYTHONPATH=$(PYTHONPATH) LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) LC_ALL=C __AA_CONFDIR=$(CONFDIR) __AA_BASEDIR=$(BASEDIR) __AA_PARSER=$(PARSER) ; $(COVERAGE_IGNORE_FAILURES_CMD) ; $(foreach test, $(wildcard test-*.py), echo ; echo === $(test) === ; $(PYTHON) -m coverage run --branch -p $(test); ) $(PYTHON) -m coverage combine coverage: .coverage coverage-report: .coverage $(PYTHON) -m coverage report --omit="$(COVERAGE_OMIT)" coverage-html: .coverage $(PYTHON) -m coverage html --omit="$(COVERAGE_OMIT)" $(HTML_COVR_ARGS) apparmor-2.13.3/utils/test/test-parser-simple-tests.py0000644000175000017500000004453713502024172020613 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import unittest from common_test import AATest, setup_all_loops, setup_aa import apparmor.aa as apparmor import os from apparmor.common import open_file_read, AppArmorException # This testcase will parse all parser/tst/simple_tests with parse_profile_data(), # except the files listed in one of the arrays below. # # Files listed in skip_startswith will be completely skipped. # Files listed in the other arrays will be checked, but with the opposite of the expected result. # XXX tests listed here will be *** SKIPPED *** XXX skip_startswith = ( # the tools don't check for conflicting x permissions (yet?) 'generated_x/conflict-', 'generated_x/ambiguous-', 'generated_x/dominate-', # 'safe' and 'unsafe' keywords 'generated_perms_safe/', # Pux and Cux (which actually mean PUx and CUx) get rejected by the tools 'generated_x/exact-', ) # testcases that should raise an exception, but don't exception_not_raised = [ # most abi/bad_* aren't detected as bad by the basic implementation in the tools 'abi/bad_10.sd', 'abi/bad_11.sd', 'abi/bad_12.sd', # invalid capabilities (like "foobar"), but syntactically correct 'capability/bad_1.sd', 'capability/bad_2.sd', 'capability/bad_3.sd', 'capability/bad_4.sd', # interesting[tm] profile name 'change_hat/bad_parsing.sd', # The tools don't detect conflicting change_profile exec modes 'change_profile/onx_conflict_unsafe1.sd', 'change_profile/onx_conflict_unsafe2.sd', # duplicated conditionals aren't detected by the tools 'generated_dbus/duplicated-conditionals-45127.sd', 'generated_dbus/duplicated-conditionals-45131.sd', 'generated_dbus/duplicated-conditionals-45124.sd', 'generated_dbus/duplicated-conditionals-45130.sd', 'generated_dbus/duplicated-conditionals-45125.sd', 'generated_dbus/duplicated-conditionals-45128.sd', 'generated_dbus/duplicated-conditionals-45129.sd', 'dbus/bad_modifier_2.sd', 'dbus/bad_regex_01.sd', 'dbus/bad_regex_02.sd', 'dbus/bad_regex_03.sd', 'dbus/bad_regex_04.sd', 'dbus/bad_regex_05.sd', 'dbus/bad_regex_06.sd', 'file/bad_re_brace_1.sd', 'file/bad_re_brace_2.sd', 'file/bad_re_brace_3.sd', 'mount/bad_opt_10.sd', 'mount/bad_opt_11.sd', 'mount/bad_opt_12.sd', 'mount/bad_opt_13.sd', 'mount/bad_opt_14.sd', 'mount/bad_opt_15.sd', 'mount/bad_opt_16.sd', 'mount/bad_opt_17.sd', 'mount/bad_opt_18.sd', 'mount/bad_opt_19.sd', 'mount/bad_opt_1.sd', 'mount/bad_opt_20.sd', 'mount/bad_opt_21.sd', 'mount/bad_opt_22.sd', 'mount/bad_opt_23.sd', 'mount/bad_opt_24.sd', 'mount/bad_opt_2.sd', 'mount/bad_opt_3.sd', 'mount/bad_opt_4.sd', 'mount/bad_opt_5.sd', 'mount/bad_opt_6.sd', 'mount/bad_opt_7.sd', 'mount/bad_opt_8.sd', 'mount/bad_opt_9.sd', 'profile/flags/flags_bad10.sd', 'profile/flags/flags_bad11.sd', 'profile/flags/flags_bad12.sd', 'profile/flags/flags_bad13.sd', 'profile/flags/flags_bad15.sd', 'profile/flags/flags_bad18.sd', 'profile/flags/flags_bad19.sd', 'profile/flags/flags_bad20.sd', 'profile/flags/flags_bad2.sd', 'profile/flags/flags_bad3.sd', 'profile/flags/flags_bad4.sd', 'profile/flags/flags_bad5.sd', 'profile/flags/flags_bad6.sd', 'profile/flags/flags_bad7.sd', 'profile/flags/flags_bad8.sd', 'profile/flags/flags_bad_debug_1.sd', 'profile/flags/flags_bad_debug_2.sd', 'profile/flags/flags_bad_debug_3.sd', 'profile/flags/flags_bad_debug_4.sd', 'profile/simple_bad_no_close_brace4.sd', 'profile/profile_ns_bad8.sd', # 'profile :ns/t' without terminating ':' 'ptrace/bad_05.sd', # actually contains a capability rule with invalid (ptrace-related) keyword 'ptrace/bad_06.sd', # actually contains a capability rule with invalid (ptrace-related) keyword 'ptrace/bad_10.sd', # peer with invalid regex 'signal/bad_21.sd', # invalid regex 'unix/bad_attr_1.sd', 'unix/bad_attr_2.sd', 'unix/bad_attr_3.sd', 'unix/bad_attr_4.sd', 'unix/bad_bind_1.sd', 'unix/bad_bind_2.sd', 'unix/bad_create_1.sd', 'unix/bad_create_2.sd', 'unix/bad_listen_1.sd', 'unix/bad_listen_2.sd', 'unix/bad_modifier_1.sd', 'unix/bad_modifier_2.sd', 'unix/bad_modifier_3.sd', 'unix/bad_modifier_4.sd', 'unix/bad_opt_1.sd', 'unix/bad_opt_2.sd', 'unix/bad_opt_3.sd', 'unix/bad_opt_4.sd', 'unix/bad_peer_1.sd', 'unix/bad_regex_01.sd', 'unix/bad_regex_02.sd', 'unix/bad_regex_03.sd', 'unix/bad_regex_04.sd', 'unix/bad_shutdown_1.sd', 'unix/bad_shutdown_2.sd', 'vars/boolean/boolean_bad_2.sd', 'vars/boolean/boolean_bad_3.sd', 'vars/boolean/boolean_bad_4.sd', 'vars/vars_bad_3.sd', 'vars/vars_bad_4.sd', 'vars/vars_bad_5.sd', 'vars/vars_bad_7.sd', 'vars/vars_bad_8.sd', 'vars/vars_bad_trailing_comma_1.sd', 'vars/vars_bad_trailing_comma_2.sd', 'vars/vars_bad_trailing_comma_3.sd', 'vars/vars_bad_trailing_comma_4.sd', 'vars/vars_dbus_bad_01.sd', 'vars/vars_dbus_bad_02.sd', 'vars/vars_dbus_bad_03.sd', 'vars/vars_dbus_bad_04.sd', 'vars/vars_dbus_bad_05.sd', 'vars/vars_dbus_bad_06.sd', 'vars/vars_dbus_bad_07.sd', 'vars/vars_file_evaluation_7.sd', 'vars/vars_file_evaluation_8.sd', # profile name in var doesn't start with / 'vars/vars_profile_name_bad_1.sd', # profile name is undefined variable 'vars/vars_profile_name_bad_2.sd', 'vars/vars_profile_name_23.sd', # attachment in var doesn't start with / 'vars/vars_profile_name_07.sd', 'vars/vars_profile_name_08.sd', 'vars/vars_profile_name_12.sd', 'vars/vars_profile_name_13.sd', 'vars/vars_profile_name_15.sd', 'vars/vars_profile_name_22.sd', 'vars/vars_recursion_1.sd', 'vars/vars_recursion_2.sd', 'vars/vars_recursion_3.sd', 'vars/vars_recursion_4.sd', 'vars/vars_simple_assignment_3.sd', 'vars/vars_simple_assignment_8.sd', 'vars/vars_simple_assignment_9.sd', 'xtrans/simple_bad_conflicting_x_10.sd', 'xtrans/simple_bad_conflicting_x_11.sd', 'xtrans/simple_bad_conflicting_x_12.sd', 'xtrans/simple_bad_conflicting_x_13.sd', 'xtrans/simple_bad_conflicting_x_2.sd', 'xtrans/simple_bad_conflicting_x_4.sd', 'xtrans/simple_bad_conflicting_x_6.sd', 'xtrans/simple_bad_conflicting_x_8.sd', 'xtrans/x-conflict.sd', ] # testcases with lines that don't match any regex and end up as "unknown line" unknown_line = [ # 'other' keyword 'file/allow/ok_other_1.sd', 'file/allow/ok_other_2.sd', 'file/ok_other_1.sd', 'file/ok_other_2.sd', 'file/ok_other_3.sd', # 'unsafe' keyword 'file/file/front_perms_ok_1.sd', 'file/front_perms_ok_1.sd', 'xtrans/simple_ok_cx_1.sd', # permissions before path and owner / audit {...} blocks 'file/file/owner/ok_1.sd', 'file/owner/ok_1.sd', 'profile/entry_mods_audit_ok1.sd', # namespace 'profile/profile_ns_named_ok1.sd', # profile keyword? 'profile/profile_ns_named_ok2.sd', # profile keyword? 'profile/profile_ns_named_ok3.sd', # profile keyword? 'profile/profile_ns_ok1.sd', 'profile/profile_ns_ok2.sd', 'profile/profile_ns_ok3.sd', # profile keyword? 'profile/re_named_ok4.sd', # profile keyword 'profile/re_ok4.sd', # multiple rules in one line 'bare_include_tests/ok_14.sd', 'bare_include_tests/ok_19.sd', 'bare_include_tests/ok_64.sd', 'bare_include_tests/ok_69.sd', # "include if exists" and various exotic "include" variants are not supported yet 'bare_include_tests/ok_11.sd', 'bare_include_tests/ok_12.sd', 'bare_include_tests/ok_13.sd', 'bare_include_tests/ok_15.sd', 'bare_include_tests/ok_16.sd', 'bare_include_tests/ok_17.sd', 'bare_include_tests/ok_18.sd', 'bare_include_tests/ok_20.sd', 'bare_include_tests/ok_26.sd', 'bare_include_tests/ok_27.sd', 'bare_include_tests/ok_28.sd', 'bare_include_tests/ok_29.sd', 'bare_include_tests/ok_30.sd', 'bare_include_tests/ok_31.sd', 'bare_include_tests/ok_61.sd', 'bare_include_tests/ok_62.sd', 'bare_include_tests/ok_63.sd', 'bare_include_tests/ok_65.sd', 'bare_include_tests/ok_66.sd', 'bare_include_tests/ok_67.sd', 'bare_include_tests/ok_68.sd', 'bare_include_tests/ok_70.sd', 'bare_include_tests/ok_76.sd', 'bare_include_tests/ok_77.sd', 'bare_include_tests/ok_78.sd', 'bare_include_tests/ok_79.sd', 'bare_include_tests/ok_80.sd', 'bare_include_tests/ok_81.sd', 'bare_include_tests/ok_82.sd', 'bare_include_tests/ok_83.sd', 'bare_include_tests/ok_84.sd', 'bare_include_tests/ok_85.sd', 'bare_include_tests/ok_86.sd', 'bare_include_tests/ok_87.sd', 'bare_include_tests/ok_88.sd', ] # testcases with various unexpected failures syntax_failure = [ # profile keyword? 'profile/re_named_ok2.sd', # Syntax Error: Unexpected hat definition found (external hat) 'change_hat/new_style4.sd', # Syntax Errors caused by boolean conditions (parse_profile_data() gets confused by the closing '}') 'conditional/defined_1.sd', 'conditional/defined_2.sd', 'conditional/else_1.sd', 'conditional/else_2.sd', 'conditional/else_3.sd', 'conditional/else_if_1.sd', 'conditional/else_if_2.sd', 'conditional/else_if_3.sd', 'conditional/else_if_5.sd', 'conditional/ok_1.sd', 'conditional/ok_2.sd', 'conditional/ok_3.sd', 'conditional/ok_4.sd', 'conditional/ok_5.sd', 'conditional/ok_6.sd', 'conditional/ok_7.sd', 'conditional/ok_8.sd', 'conditional/ok_9.sd', 'conditional/stress_1.sd', # unexpected uppercase vs. lowercase in *x rules 'file/ok_5.sd', # Invalid mode UX 'file/ok_2.sd', # Invalid mode RWM 'file/ok_4.sd', # Invalid mode iX 'xtrans/simple_ok_pix_1.sd', # Invalid mode pIx 'xtrans/simple_ok_pux_1.sd', # Invalid mode rPux # unexpected uppercase vs. lowercase in *x rules - generated_perms_leading directory 'generated_perms_leading/exact-re-Puxtarget.sd', 'generated_perms_leading/dominate-ownerCuxtarget2.sd', 'generated_perms_leading/ambiguous-Cux.sd', 'generated_perms_leading/dominate-ownerPux.sd', 'generated_perms_leading/exact-re-ownerPux.sd', 'generated_perms_leading/overlap-ownerCuxtarget.sd', 'generated_perms_leading/exact-re-ownerCuxtarget.sd', 'generated_perms_leading/dominate-Puxtarget2.sd', 'generated_perms_leading/dominate-ownerCuxtarget.sd', 'generated_perms_leading/dominate-ownerPuxtarget.sd', 'generated_perms_leading/ambiguous-Pux.sd', 'generated_perms_leading/ambiguous-Cuxtarget2.sd', 'generated_perms_leading/exact-Puxtarget2.sd', 'generated_perms_leading/ambiguous-ownerCux.sd', 'generated_perms_leading/exact-ownerPux.sd', 'generated_perms_leading/ambiguous-ownerPuxtarget.sd', 'generated_perms_leading/exact-re-ownerPuxtarget.sd', 'generated_perms_leading/exact-re-Cuxtarget.sd', 'generated_perms_leading/exact-re-Puxtarget2.sd', 'generated_perms_leading/dominate-Cux.sd', 'generated_perms_leading/exact-re-ownerCuxtarget2.sd', 'generated_perms_leading/ambiguous-ownerCuxtarget.sd', 'generated_perms_leading/exact-re-Cuxtarget2.sd', 'generated_perms_leading/ambiguous-Puxtarget.sd', 'generated_perms_leading/overlap-Puxtarget.sd', 'generated_perms_leading/ambiguous-Puxtarget2.sd', 'generated_perms_leading/overlap-Puxtarget2.sd', 'generated_perms_leading/exact-Puxtarget.sd', 'generated_perms_leading/overlap-ownerPuxtarget.sd', 'generated_perms_leading/exact-ownerCuxtarget.sd', 'generated_perms_leading/exact-re-ownerCux.sd', 'generated_perms_leading/exact-ownerPuxtarget2.sd', 'generated_perms_leading/exact-ownerCux.sd', 'generated_perms_leading/overlap-Cuxtarget2.sd', 'generated_perms_leading/ambiguous-Cuxtarget.sd', 'generated_perms_leading/ambiguous-ownerPuxtarget2.sd', 'generated_perms_leading/dominate-ownerCux.sd', 'generated_perms_leading/exact-Pux.sd', 'generated_perms_leading/exact-Cuxtarget.sd', 'generated_perms_leading/overlap-ownerCuxtarget2.sd', 'generated_perms_leading/overlap-Pux.sd', 'generated_perms_leading/overlap-ownerPux.sd', 'generated_perms_leading/ambiguous-ownerCuxtarget2.sd', 'generated_perms_leading/exact-re-Cux.sd', 'generated_perms_leading/exact-re-Pux.sd', 'generated_perms_leading/overlap-Cuxtarget.sd', 'generated_perms_leading/exact-re-ownerPuxtarget2.sd', 'generated_perms_leading/exact-Cuxtarget2.sd', 'generated_perms_leading/exact-Cux.sd', 'generated_perms_leading/overlap-Cux.sd', 'generated_perms_leading/overlap-ownerCux.sd', 'generated_perms_leading/exact-ownerPuxtarget.sd', 'generated_perms_leading/dominate-Pux.sd', 'generated_perms_leading/exact-ownerCuxtarget2.sd', 'generated_perms_leading/dominate-Puxtarget.sd', 'generated_perms_leading/ambiguous-ownerPux.sd', 'generated_perms_leading/overlap-ownerPuxtarget2.sd', 'generated_perms_leading/dominate-Cuxtarget2.sd', 'generated_perms_leading/dominate-Cuxtarget.sd', 'generated_perms_leading/dominate-ownerPuxtarget2.sd', # escaping with \ 'file/ok_embedded_spaces_4.sd', # \-escaped space 'file/file/ok_embedded_spaces_4.sd', # \-escaped space 'file/ok_quoted_4.sd', # quoted string including \" # misc 'vars/vars_dbus_8.sd', # Path doesn't start with / or variable: {/@{TLDS}/foo,/com/@{DOMAINS}} 'vars/vars_simple_assignment_12.sd', # Redefining existing variable @{BAR} ('\' not handled) 'rewrite/alias_good_5.sd', # Values added to a non-existing variable @{FOO} (defined in include, lp:1331856) 'bare_include_tests/ok_2.sd', # two #include<...> in one line ] class TestParseParserTests(AATest): tests = [] # filled by parse_test_profiles() def _run_test(self, params, expected): with open_file_read(params['file']) as f_in: data = f_in.readlines() if params['disabled']: # skip disabled testcases return if params['tools_wrong']: # if the tools are marked as being wrong about a profile, expect the opposite result # this makes sure we notice any behaviour change, especially not being wrong anymore expected = not expected if expected: apparmor.parse_profile_data(data, params['file'], 0) else: with self.assertRaises(AppArmorException): apparmor.parse_profile_data(data, params['file'], 0) def parse_test_profiles(file_with_path): '''parse the test-related headers of a profile (for example EXRESULT) and add the profile to the set of tests''' exresult = None exresult_found = False description = None todo = False disabled = False with open_file_read(file_with_path) as f_in: data = f_in.readlines() relfile = os.path.relpath(file_with_path, apparmor.profile_dir) for line in data: if line.startswith('#=EXRESULT '): exresult = line.split()[1] if exresult == 'PASS': exresult == True exresult_found = True elif exresult == 'FAIL': exresult = False exresult_found = True else: raise Exception('%s contains unknown EXRESULT %s' % (file_with_path, exresult)) elif line.upper().startswith('#=DESCRIPTION '): description = line.split()[1] elif line.rstrip() == '#=TODO': todo = True elif line.rstrip() == '#=DISABLED': disabled = True if not exresult_found: raise Exception('%s does not contain EXRESULT' % file_with_path) if not description: raise Exception('%s does not contain description' % file_with_path) tools_wrong = False if relfile in exception_not_raised: if exresult: raise Exception("%s listed in exception_not_raised, but has EXRESULT PASS" % file_with_path) tools_wrong = 'EXCEPTION_NOT_RAISED' elif relfile.startswith(skip_startswith): return 1 # XXX *** SKIP *** those tests elif relfile in unknown_line: if not exresult: raise Exception("%s listed in unknown_line, but has EXRESULT FAIL" % file_with_path) tools_wrong = 'UNKNOWN_LINE' elif relfile in syntax_failure: if not exresult: raise Exception("%s listed in syntax_failure, but has EXRESULT FAIL" % file_with_path) tools_wrong = 'SYNTAX_FAILURE' params = { 'file': file_with_path, 'relfile': relfile, 'todo': todo, 'disabled': disabled, 'tools_wrong': tools_wrong, 'exresult': exresult, } TestParseParserTests.tests.append((params, exresult)) return 0 def find_and_setup_test_profiles(profile_dir): '''find all profiles in the given profile_dir, excluding - skippable files - include directories - files in the main directory (readme, todo etc.) ''' skipped = 0 profile_dir = os.path.abspath(profile_dir) apparmor.profile_dir = profile_dir print('Searching for parser simpe_tests... (this will take a while)') for root, dirs, files in os.walk(profile_dir): relpath = os.path.relpath(root, profile_dir) if relpath == '.': # include files are checked as part of the profiles that include them (also, they don't contain EXRESULT) dirs.remove('includes') dirs.remove('include_tests') dirs.remove('includes-preamble') for file in files: file_with_path = os.path.join(root, file) if not apparmor.is_skippable_file(file) and relpath != '.': skipped += parse_test_profiles(file_with_path) if skipped: print('Skipping %s test profiles listed in skip_startswith.' % skipped) print('Running %s parser simple_tests...' % len(TestParseParserTests.tests)) setup_aa(apparmor) find_and_setup_test_profiles('../../parser/tst/simple_tests/') setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/test-file.py0000644000175000017500000020707313502024172015603 0ustar jjjj#!/usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2015 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import unittest from collections import namedtuple from common_test import AATest, setup_all_loops from apparmor.rule.file import FileRule, FileRuleset from apparmor.rule import BaseRule import apparmor.severity as severity from apparmor.common import AppArmorException, AppArmorBug from apparmor.logparser import ReadLog from apparmor.translations import init_translation _ = init_translation() exp = namedtuple('exp', ['audit', 'allow_keyword', 'deny', 'comment', 'path', 'all_paths', 'perms', 'all_perms', 'exec_perms', 'target', 'all_targets', 'owner', 'file_keyword', 'leading_perms']) # --- tests for single FileRule --- # class FileTest(AATest): def _compare_obj(self, obj, expected): self.assertEqual(obj.allow_keyword, expected.allow_keyword) self.assertEqual(obj.audit, expected.audit) self.assertEqual(obj.deny, expected.deny) self.assertEqual(obj.comment, expected.comment) self._assertEqual_aare(obj.path, expected.path) self.assertEqual(obj.perms, expected.perms) self.assertEqual(obj.exec_perms, expected.exec_perms) self._assertEqual_aare(obj.target, expected.target) self.assertEqual(obj.owner, expected.owner) self.assertEqual(obj.file_keyword, expected.file_keyword) self.assertEqual(obj.leading_perms, expected.leading_perms) # Note: there's no all_ field for exec_perms, owner, file_keyword and leading_perms self.assertEqual(obj.all_paths, expected.all_paths) self.assertEqual(obj.all_perms, expected.all_perms) self.assertEqual(obj.all_targets, expected.all_targets) def _assertEqual_aare(self, obj, expected): if obj: self.assertEqual(obj.regex, expected) else: self.assertEqual(obj, expected) class FileTestParse(FileTest): tests = [ # FileRule object audit allow deny comment path all_paths perms all? exec_perms target all? owner file keyword leading perms # bare file rules ('file,' , exp(False, False, False, '', None, True , None, True, None, None, True, False, False, False )), ('allow file,' , exp(False, True, False, '', None, True , None, True, None, None, True, False, False, False )), ('audit deny owner file, # cmt' , exp(True, False, True, ' # cmt', None, True , None, True, None, None, True, True, False, False )), # "normal" file rules ('/foo r,' , exp(False, False, False, '', '/foo', False, {'r'}, False, None, None, True, False, False, False )), ('file /foo rwix,' , exp(False, False, False, '', '/foo', False, {'r', 'w'}, False, 'ix', None, True, False, True, False )), ('/foo Px -> bar,' , exp(False, False, False, '', '/foo', False, set(), False, 'Px', 'bar', False, False, False, False )), ('@{PROC}/[a-z]** mr,' , exp(False, False, False, '', '@{PROC}/[a-z]**',False, {'r', 'm'}, False, None, None, True, False, False, False )), ('audit /tmp/foo r,' , exp(True, False, False, '', '/tmp/foo', False, {'r'}, False, None, None, True, False, False, False )), ('audit deny /tmp/foo r,' , exp(True, False, True, '', '/tmp/foo', False, {'r'}, False, None, None, True, False, False, False )), ('audit deny /tmp/foo rx,' , exp(True, False, True, '', '/tmp/foo', False, {'r'}, False, 'x', None, True, False, False, False )), ('allow /tmp/foo ra,' , exp(False, True, False, '', '/tmp/foo', False, {'r', 'a'}, False, None, None, True, False, False, False )), ('audit allow /tmp/foo ra,' , exp(True, True, False, '', '/tmp/foo', False, {'r', 'a'}, False, None, None, True, False, False, False )), # file rules with leading permission ('r /foo,' , exp(False, False, False, '', '/foo', False, {'r'}, False, None, None, True, False, False, True )), ('file rwix /foo,' , exp(False, False, False, '', '/foo', False, {'r', 'w'}, False, 'ix', None, True, False, True, True )), ('Px /foo -> bar,' , exp(False, False, False, '', '/foo', False, set(), False, 'Px', 'bar', False, False, False, True )), ('mr @{PROC}/[a-z]**,' , exp(False, False, False, '', '@{PROC}/[a-z]**',False, {'r', 'm'}, False, None, None, True, False, False, True )), ('audit r /tmp/foo,' , exp(True, False, False, '', '/tmp/foo', False, {'r'}, False, None, None, True, False, False, True )), ('audit deny r /tmp/foo,' , exp(True, False, True, '', '/tmp/foo', False, {'r'}, False, None, None, True, False, False, True )), ('allow ra /tmp/foo,' , exp(False, True, False, '', '/tmp/foo', False, {'r', 'a'}, False, None, None, True, False, False, True )), ('audit allow ra /tmp/foo,' , exp(True, True, False, '', '/tmp/foo', False, {'r', 'a'}, False, None, None, True, False, False, True )), # duplicated (but not conflicting) permissions ('/foo PxPxPxPxrwPx -> bar,' , exp(False, False, False, '', '/foo', False, {'r', 'w'}, False, 'Px', 'bar', False, False, False, False )), ('/foo CixCixrwCix -> bar, ' , exp(False, False, False, '', '/foo', False, {'r', 'w'}, False, 'Cix', 'bar', False, False, False, False )), ] def _run_test(self, rawrule, expected): self.assertTrue(FileRule.match(rawrule)) obj = FileRule.parse(rawrule) self.assertEqual(rawrule.strip(), obj.raw_rule) self._compare_obj(obj, expected) class FileTestParseInvalid(FileTest): tests = [ ('/foo x,' , AppArmorException), # should be *x ('/foo raw,' , AppArmorException), # r and a conflict ('deny /foo ix,' , AppArmorException), # endy only allows x, but not *x ('deny /foo Px,' , AppArmorException), # deny only allows x, but not *x ('deny /foo Pi,' , AppArmorException), # missing 'x', and P not allowed ('allow /foo x,' , AppArmorException), # should be *x ('/foo Pxrix,' , AppArmorException), # exec mode conflict ('/foo PixUx,' , AppArmorException), # exec mode conflict ('/foo PxUx,' , AppArmorException), # exec mode conflict ('/foo PUxPix,' , AppArmorException), # exec mode conflict ('/foo Pi,' , AppArmorException), # missing 'x' ] def _run_test(self, rawrule, expected): self.assertTrue(FileRule.match(rawrule)) # the above invalid rules still match the main regex! with self.assertRaises(expected): FileRule.parse(rawrule) class FileTestNonMatch(AATest): tests = [ ('file /foo,' , False ), ('file rw,' , False ), ('file -> bar,' , False ), ('file Px -> bar,' , False ), ('/foo bar,' , False ), ('dbus /foo,' , False ), ] def _run_test(self, rawrule, expected): self.assertFalse(FileRule.match(rawrule)) class FileTestParseFromLog(FileTest): def test_file_from_log(self): parser = ReadLog('', '', '', '') event = 'Nov 11 07:33:07 myhost kernel: [50812.879558] type=1502 audit(1236774787.169:369): operation="inode_permission" requested_mask="::r" denied_mask="::r" fsuid=1000 name="/bin/dash" pid=13726 profile="/bin/foobar"' parsed_event = parser.parse_event(event) self.assertEqual(parsed_event, { 'request_mask': '::r', 'denied_mask': '::r', 'error_code': 0, 'magic_token': 0, 'parent': 0, 'profile': '/bin/foobar', 'operation': 'inode_permission', 'name': '/bin/dash', 'name2': None, 'resource': None, 'info': None, 'aamode': 'PERMITTING', 'time': 1236774787, 'active_hat': None, 'pid': 13726, 'task': 0, 'attr': None, 'family': None, 'protocol': None, 'sock_type': None, }) #FileRule# path, perms, exec_perms, target, owner, file_keyword, leading_perms #obj = FileRule(parsed_event['name'], parsed_event['denied_mask'], None, FileRule.ALL, False, False, False, ) obj = FileRule(parsed_event['name'], 'r', None, FileRule.ALL, False, False, False, ) # XXX handle things like '::r' # XXX split off exec perms? # audit allow deny comment path all_paths perms all? exec_perms target all? owner file keyword leading perms expected = exp(False, False, False, '', '/bin/dash', False, {'r'}, False, None, None, True, False, False, False ) self._compare_obj(obj, expected) self.assertEqual(obj.get_raw(1), ' /bin/dash r,') class FileFromInit(FileTest): tests = [ #FileRule# path, perms, exec_perms, target, owner, file_keyword, leading_perms (FileRule( '/foo', 'rw', None, FileRule.ALL, False, False, False, audit=True, deny=True ), #exp# audit allow deny comment path all_paths perms all? exec_perms target all? owner file keyword leading perms exp( True, False, True, '', '/foo', False, {'r', 'w'}, False, None, None, True, False, False, False )), #FileRule# path, perms, exec_perms, target, owner, file_keyword, leading_perms (FileRule( '/foo', None, 'Pix', 'bar_prof', True, True, True, allow_keyword=True ), #exp# audit allow deny comment path all_paths perms all? exec_perms target all? owner file keyword leading perms exp( False, True, False, '', '/foo', False, set(), False, 'Pix', 'bar_prof', False, True, True, True )), ] def _run_test(self, obj, expected): self._compare_obj(obj, expected) class InvalidFileInit(AATest): tests = [ #FileRule# path, perms, exec_perms, target, owner, file_keyword, leading_perms # empty fields ( ( '', 'rw', 'ix', '/bar', False, False, False ), AppArmorBug), # OK ( '/foo', '', 'ix', '/bar', False, False, False ), AppArmorBug), ( ( '/foo', 'rw', '', '/bar', False, False, False ), AppArmorBug), ( ( '/foo', 'rw', 'ix', '', False, False, False ), AppArmorBug), # whitespace fields ( ( ' ', 'rw', 'ix', '/bar', False, False, False ), AppArmorBug), ( ( '/foo', ' ', 'ix', '/bar', False, False, False ), AppArmorException), ( ( '/foo', 'rw', ' ', '/bar', False, False, False ), AppArmorBug), ( ( '/foo', 'rw', 'ix', ' ', False, False, False ), AppArmorBug), # wrong type - dict() ( ( dict(), 'rw', 'ix', '/bar', False, False, False ), AppArmorBug), ( ( '/foo', dict(), 'ix', '/bar', False, False, False ), AppArmorBug), ( ( '/foo', 'rw', dict(), '/bar', False, False, False ), AppArmorBug), ( ( '/foo', 'rw', 'ix', dict(), False, False, False ), AppArmorBug), ( ( '/foo', 'rw', 'ix', '/bar', dict(), False, False ), AppArmorBug), ( ( '/foo', 'rw', 'ix', '/bar', False, dict(), False ), AppArmorBug), ( ( '/foo', 'rw', 'ix', '/bar', False, False, dict() ), AppArmorBug), # wrong type - None ( ( None, 'rw', 'ix', '/bar', False, False, False ), AppArmorBug), # OK ( '/foo', None, 'ix', '/bar', False, False, False ), AppArmorBug), # OK ( '/foo', 'rw', None, '/bar', False, False, False ), AppArmorBug), ( ( '/foo', 'rw', 'ix', None, False, False, False ), AppArmorBug), ( ( '/foo', 'rw', 'ix', '/bar', None, False, False ), AppArmorBug), ( ( '/foo', 'rw', 'ix', '/bar', False, None, False ), AppArmorBug), ( ( '/foo', 'rw', 'ix', '/bar', False, False, None ), AppArmorBug), # misc ( ( '/foo', 'rwa', 'ix', '/bar', False, False, False ), AppArmorException), # 'r' and 'a' conflict ( ( '/foo', None, 'rw', '/bar', False, False, False ), AppArmorBug), # file perms in exec perms parameter ( ( '/foo', 'ix', None, '/bar', False, False, False ), AppArmorBug), # exec perms in file perms parameter ( ( 'foo', 'rw', 'ix', '/bar', False, False, False ), AppArmorException), # path doesn't start with / ( ( '/foo', 'rb', 'ix', '/bar', False, False, False ), AppArmorException), # invalid file mode 'b' (str) ( ( '/foo', {'b'}, 'ix', '/bar', False, False, False ), AppArmorBug), # invalid file mode 'b' (str) ( ( '/foo', 'rw', 'ax', '/bar', False, False, False ), AppArmorBug), # invalid exec mode 'ax' ( ( '/foo', 'rw', 'x', '/bar', False, False, False ), AppArmorException), # plain 'x' is only allowed in deny rules ( ( FileRule.ALL, FileRule.ALL, None, '/bar', False, False, False ), AppArmorBug), # plain 'file,' doesn't allow exec target ] def _run_test(self, params, expected): with self.assertRaises(expected): FileRule(params[0], params[1], params[2], params[3], params[4], params[5], params[6]) def test_missing_params_1(self): with self.assertRaises(TypeError): FileRule( '/foo') def test_missing_params_2(self): with self.assertRaises(TypeError): FileRule( '/foo', 'rw') def test_missing_params_3(self): with self.assertRaises(TypeError): FileRule( '/foo', 'rw', 'ix') def test_missing_params_4(self): with self.assertRaises(TypeError): FileRule( '/foo', 'rw', 'ix', '/bar') def test_deny_ix(self): with self.assertRaises(AppArmorException): FileRule( '/foo', 'rw', 'ix', '/bar', False, False, False, deny=True) class InvalidFileTest(AATest): def _check_invalid_rawrule(self, rawrule): obj = None self.assertFalse(FileRule.match(rawrule)) with self.assertRaises(AppArmorException): obj = FileRule(FileRule.parse(rawrule)) self.assertIsNone(obj, 'FileRule handed back an object unexpectedly') def test_invalid_file_missing_comma_1(self): self._check_invalid_rawrule('file') # missing comma def test_invalid_non_FileRule(self): self._check_invalid_rawrule('signal,') # not a file rule class BrokenFileTest(AATest): def AASetup(self): #FileRule# path, perms, exec_perms, target, owner, file_keyword, leading_perms self.obj = FileRule('/foo', 'rw', 'ix', '/bar', False, False, False) def test_empty_data_1(self): self.obj.path = '' # no path set, and ALL not set with self.assertRaises(AppArmorBug): self.obj.get_clean(1) def test_empty_data_2(self): self.obj.perms = '' self.obj.exec_perms = '' # no perms or exec_perms set, and ALL not set with self.assertRaises(AppArmorBug): self.obj.get_clean(1) def test_empty_data_3(self): self.obj.target = '' # no target set, and ALL not set with self.assertRaises(AppArmorBug): self.obj.get_clean(1) def test_unexpected_all_1(self): self.obj.all_paths = FileRule.ALL # all_paths and all_perms must be in sync with self.assertRaises(AppArmorBug): self.obj.get_clean(1) def test_unexpected_all_2(self): self.obj.all_perms = FileRule.ALL # all_paths and all_perms must be in sync with self.assertRaises(AppArmorBug): self.obj.get_clean(1) class FileGlobTest(AATest): def _run_test(self, params, expected): exp_can_glob, exp_can_glob_ext, exp_rule_glob, exp_rule_glob_ext = expected # test glob() rule_obj = FileRule.parse(params) self.assertEqual(exp_can_glob, rule_obj.can_glob) self.assertEqual(exp_can_glob_ext, rule_obj.can_glob_ext) rule_obj.glob() self.assertEqual(rule_obj.get_clean(), exp_rule_glob) # test glob_ext() rule_obj = FileRule.parse(params) self.assertEqual(exp_can_glob, rule_obj.can_glob) self.assertEqual(exp_can_glob_ext, rule_obj.can_glob_ext) rule_obj.glob_ext() self.assertEqual(rule_obj.get_clean(), exp_rule_glob_ext) # These tests are meant to ensure AARE integration in FileRule works as expected. # test-aare.py has more comprehensive globbing tests. tests = [ # rule can glob can glob_ext globbed rule globbed_ext rule ('/foo/bar r,', (True, True, '/foo/* r,', '/foo/bar r,')), ('/foo/* r,', (True, True, '/** r,', '/foo/* r,')), ('/foo/bar.xy r,', (True, True, '/foo/* r,', '/foo/*.xy r,')), ('/foo/*.xy r,', (True, True, '/foo/* r,', '/**.xy r,')), ('file,', (False, False, 'file,', 'file,')), # bare 'file,' rules can't be globbed ] class WriteFileTest(AATest): def _run_test(self, rawrule, expected): self.assertTrue(FileRule.match(rawrule), 'FileRule.match() failed') obj = FileRule.parse(rawrule) clean = obj.get_clean() raw = obj.get_raw() self.assertEqual(expected.strip(), clean, 'unexpected clean rule') self.assertEqual(rawrule.strip(), raw, 'unexpected raw rule') tests = [ # raw rule clean rule ('file,' , 'file,'), (' file , # foo ' , 'file, # foo'), (' audit file /foo r,' , 'audit file /foo r,'), (' audit file /foo lwr,' , 'audit file /foo rwl,'), (' audit file /foo Pxrm -> bar,' , 'audit file /foo mrPx -> bar,'), (' deny file /foo r,' , 'deny file /foo r,'), (' deny file /foo wr,' , 'deny file /foo rw,'), (' allow file /foo Pxrm -> bar,' , 'allow file /foo mrPx -> bar,'), (' deny owner /foo r,' , 'deny owner /foo r,'), (' deny owner /foo wr,' , 'deny owner /foo rw,'), (' allow owner /foo Pxrm -> bar,' , 'allow owner /foo mrPx -> bar,'), (' /foo r,' , '/foo r,'), (' /foo lwr,' , '/foo rwl,'), (' /foo Pxrm -> bar,' , '/foo mrPx -> bar,'), # with leading permissions (' audit file r /foo,' , 'audit file r /foo,'), (' audit file lwr /foo,' , 'audit file rwl /foo,'), (' audit file Pxrm /foo -> bar,' , 'audit file mrPx /foo -> bar,'), (' deny file r /foo,' , 'deny file r /foo,'), (' deny file wr /foo ,' , 'deny file rw /foo,'), (' allow file Pxmr /foo -> bar,' , 'allow file mrPx /foo -> bar,'), (' deny owner r /foo ,' , 'deny owner r /foo,'), (' deny owner wr /foo ,' , 'deny owner rw /foo,'), (' allow owner Pxrm /foo -> bar,' , 'allow owner mrPx /foo -> bar,'), (' r /foo ,' , 'r /foo,'), (' klwr /foo ,' , 'rwlk /foo,'), (' Pxrm /foo -> bar,' , 'mrPx /foo -> bar,'), ] def test_write_manually_1(self): #FileRule# path, perms, exec_perms, target, owner, file_keyword, leading_perms obj = FileRule( '/foo', 'rw', 'Px', '/bar', False, True, False, allow_keyword=True) expected = ' allow file /foo rwPx -> /bar,' self.assertEqual(expected, obj.get_clean(2), 'unexpected clean rule') self.assertEqual(expected, obj.get_raw(2), 'unexpected raw rule') def test_write_manually_2(self): #FileRule# path, perms, exec_perms, target, owner, file_keyword, leading_perms obj = FileRule( '/foo', 'rw', 'x', FileRule.ALL, True, False, True, deny=True) expected = ' deny owner rwx /foo,' self.assertEqual(expected, obj.get_clean(2), 'unexpected clean rule') self.assertEqual(expected, obj.get_raw(2), 'unexpected raw rule') def test_write_any_exec(self): obj = FileRule( '/foo', 'rw', FileRule.ANY_EXEC,'/bar', False, False, False) with self.assertRaises(AppArmorBug): obj.get_clean() class FileCoveredTest(AATest): def _run_test(self, param, expected): obj = FileRule.parse(self.rule) check_obj = FileRule.parse(param) self.assertTrue(FileRule.match(param)) self.assertEqual(obj.is_equal(check_obj), expected[0], 'Mismatch in is_equal, expected %s' % expected[0]) self.assertEqual(obj.is_equal(check_obj, True), expected[1], 'Mismatch in is_equal/strict, expected %s' % expected[1]) self.assertEqual(obj.is_covered(check_obj), expected[2], 'Mismatch in is_covered, expected %s' % expected[2]) self.assertEqual(obj.is_covered(check_obj, True, True), expected[3], 'Mismatch in is_covered/exact, expected %s' % expected[3]) class FileCoveredTest_01(FileCoveredTest): rule = 'file /foo r,' tests = [ # rule equal strict equal covered covered exact ('file /foo r,' , [ True , True , True , True ]), ('file /foo r ,' , [ True , False , True , True ]), ('allow file /foo r,' , [ True , False , True , True ]), ('allow /foo r, # comment' , [ True , False , True , True ]), ('allow owner /foo r,' , [ False , False , True , True ]), ('/foo r -> bar,' , [ False , False , True , True ]), ('file r /foo,' , [ True , False , True , True ]), ('allow file r /foo,' , [ True , False , True , True ]), ('allow r /foo, # comment' , [ True , False , True , True ]), ('allow owner r /foo,' , [ False , False , True , True ]), ('r /foo -> bar,' , [ False , False , True , True ]), ('file,' , [ False , False , False , False ]), ('file /foo w,' , [ False , False , False , False ]), ('file /foo rw,' , [ False , False , False , False ]), ('file /bar r,' , [ False , False , False , False ]), ('audit /foo r,' , [ False , False , False , False ]), ('audit file,' , [ False , False , False , False ]), ('audit deny /foo r,' , [ False , False , False , False ]), ('deny file /foo r,' , [ False , False , False , False ]), ('/foo rPx,' , [ False , False , False , False ]), ('/foo Pxr,' , [ False , False , False , False ]), ('/foo Px,' , [ False , False , False , False ]), ('/foo ix,' , [ False , False , False , False ]), ('/foo ix -> bar,' , [ False , False , False , False ]), ('/foo rPx -> bar,' , [ False , False , False , False ]), ] class FileCoveredTest_02(FileCoveredTest): rule = 'audit /foo r,' tests = [ # rule equal strict equal covered covered exact ('file /foo r,' , [ False , False , True , False ]), ('allow file /foo r,' , [ False , False , True , False ]), ('allow /foo r, # comment' , [ False , False , True , False ]), ('allow owner /foo r,' , [ False , False , True , False ]), ('/foo r -> bar,' , [ False , False , True , False ]), ('file r /foo,' , [ False , False , True , False ]), ('allow file r /foo,' , [ False , False , True , False ]), ('allow r /foo, # comment' , [ False , False , True , False ]), ('allow owner r /foo,' , [ False , False , True , False ]), ('r /foo -> bar,' , [ False , False , True , False ]), # XXX exact ('file,' , [ False , False , False , False ]), ('file /foo w,' , [ False , False , False , False ]), ('file /foo rw,' , [ False , False , False , False ]), ('file /bar r,' , [ False , False , False , False ]), ('audit /foo r,' , [ True , True , True , True ]), ('audit file,' , [ False , False , False , False ]), ('audit deny /foo r,' , [ False , False , False , False ]), ('deny file /foo r,' , [ False , False , False , False ]), ('/foo rPx,' , [ False , False , False , False ]), ('/foo Pxr,' , [ False , False , False , False ]), ('/foo Px,' , [ False , False , False , False ]), ('/foo ix,' , [ False , False , False , False ]), ('/foo ix -> bar,' , [ False , False , False , False ]), ('/foo rPx -> bar,' , [ False , False , False , False ]), ] class FileCoveredTest_03(FileCoveredTest): rule = '/foo mrwPx,' tests = [ # rule equal strict equal covered covered exact ('file /foo r,' , [ False , False , True , True ]), ('allow file /foo r,' , [ False , False , True , True ]), ('allow /foo r, # comment' , [ False , False , True , True ]), ('allow owner /foo r,' , [ False , False , True , True ]), ('/foo r -> bar,' , [ False , False , True , True ]), ('file r /foo,' , [ False , False , True , True ]), ('allow file r /foo,' , [ False , False , True , True ]), ('allow r /foo, # comment' , [ False , False , True , True ]), ('allow owner r /foo,' , [ False , False , True , True ]), ('r /foo -> bar,' , [ False , False , True , True ]), ('file,' , [ False , False , False , False ]), ('file /foo w,' , [ False , False , True , True ]), ('file /foo rw,' , [ False , False , True , True ]), ('file /bar r,' , [ False , False , False , False ]), ('audit /foo r,' , [ False , False , False , False ]), ('audit file,' , [ False , False , False , False ]), ('audit deny /foo r,' , [ False , False , False , False ]), ('deny file /foo r,' , [ False , False , False , False ]), ('/foo mrwPx,' , [ True , True , True , True ]), ('/foo wPxrm,' , [ True , False , True , True ]), ('/foo rm,' , [ False , False , True , True ]), ('/foo Px,' , [ False , False , True , True ]), ('/foo ix,' , [ False , False , False , False ]), ('/foo ix -> bar,' , [ False , False , False , False ]), ('/foo mrwPx -> bar,' , [ False , False , False , False ]), ] class FileCoveredTest_04(FileCoveredTest): rule = '/foo mrwPx -> bar,' tests = [ # rule equal strict equal covered covered exact ('file /foo r,' , [ False , False , True , True ]), ('allow file /foo r,' , [ False , False , True , True ]), ('allow /foo r, # comment' , [ False , False , True , True ]), ('allow owner /foo r,' , [ False , False , True , True ]), ('/foo r -> bar,' , [ False , False , True , True ]), ('file r /foo,' , [ False , False , True , True ]), ('allow file r /foo,' , [ False , False , True , True ]), ('allow r /foo, # comment' , [ False , False , True , True ]), ('allow owner r /foo,' , [ False , False , True , True ]), ('r /foo -> bar,' , [ False , False , True , True ]), ('file,' , [ False , False , False , False ]), ('file /foo w,' , [ False , False , True , True ]), ('file /foo rw,' , [ False , False , True , True ]), ('file /bar r,' , [ False , False , False , False ]), ('audit /foo r,' , [ False , False , False , False ]), ('audit file,' , [ False , False , False , False ]), ('audit deny /foo r,' , [ False , False , False , False ]), ('deny file /foo r,' , [ False , False , False , False ]), ('/foo mrwPx,' , [ False , False , False , False ]), ('/foo wPxrm,' , [ False , False , False , False ]), ('/foo rm,' , [ False , False , True , True ]), ('/foo Px,' , [ False , False , False , False ]), ('/foo ix,' , [ False , False , False , False ]), ('/foo ix -> bar,' , [ False , False , False , False ]), ('/foo mrwPx -> bar,' , [ True , True , True , True ]), ] class FileCoveredTest_05(FileCoveredTest): rule = 'file,' tests = [ # rule equal strict equal covered covered exact ('file /foo r,' , [ False , False , True , True ]), ('allow file /foo r,' , [ False , False , True , True ]), ('allow /foo r, # comment' , [ False , False , True , True ]), ('allow owner /foo r,' , [ False , False , True , True ]), ('/foo r -> bar,' , [ False , False , True , True ]), ('file r /foo,' , [ False , False , True , True ]), ('allow file r /foo,' , [ False , False , True , True ]), ('allow r /foo, # comment' , [ False , False , True , True ]), ('allow owner r /foo,' , [ False , False , True , True ]), ('r /foo -> bar,' , [ False , False , True , True ]), ('file,' , [ True , True , True , True ]), ('file /foo w,' , [ False , False , True , True ]), ('file /foo rw,' , [ False , False , True , True ]), ('file /bar r,' , [ False , False , True , True ]), ('audit /foo r,' , [ False , False , False , False ]), ('audit file,' , [ False , False , False , False ]), ('audit deny /foo r,' , [ False , False , False , False ]), ('deny file /foo r,' , [ False , False , False , False ]), ('/foo mrwPx,' , [ False , False , False , False ]), ('/foo wPxrm,' , [ False , False , False , False ]), ('/foo rm,' , [ False , False , True , True ]), ('/foo Px,' , [ False , False , False , False ]), ('/foo ix,' , [ False , False , False , False ]), ('/foo ix -> bar,' , [ False , False , False , False ]), ('/foo mrwPx -> bar,' , [ False , False , False , False ]), ] class FileCoveredTest_06(FileCoveredTest): rule = 'deny /foo w,' tests = [ # rule equal strict equal covered covered exact ('/foo w,' , [ False , False , False , False ]), ('/foo a,' , [ False , False , False , False ]), ('deny /foo w,' , [ True , True , True , True ]), ('deny /foo a,' , [ False , False , True , True ]), ] class FileCoveredTest_07(FileCoveredTest): rule = '/foo w,' tests = [ # rule equal strict equal covered covered exact ('/foo w,' , [ True , True , True , True ]), ('/foo a,' , [ False , False , True , True ]), ('deny /foo w,' , [ False , False , False , False ]), ('deny /foo a,' , [ False , False , False , False ]), ] class FileCoveredTest_ManualOrInvalid(AATest): def AASetup(self): #FileRule# path, perms, exec_perms, target, owner, file_keyword, leading_perms self.obj = FileRule( '/foo', 'rw', 'ix', '/bar', False, False, False) self.testobj = FileRule( '/foo', 'rw', 'ix', '/bar', False, False, False) def test_covered_owner_1(self): # testobj with 'owner' self.testobj = FileRule( '/foo', 'rw', 'ix', '/bar', True, False, False) self.assertTrue(self.obj.is_covered(self.testobj)) def test_covered_owner_2(self): # obj with 'owner' self.obj = FileRule( '/foo', 'rw', 'ix', '/bar', True, False, False) self.assertFalse(self.obj.is_covered(self.testobj)) def test_equal_all_perms(self): self.testobj.all_perms = True # that makes testobj invalid, but that's the only way to survive the 'perms' comparison self.assertFalse(self.obj.is_equal(self.testobj)) def test_equal_file_keyword(self): # testobj with file_keyword self.testobj = FileRule( '/foo', 'rw', 'ix', '/bar', False, True, False) self.assertTrue(self.obj.is_equal(self.testobj, strict=False)) self.assertFalse(self.obj.is_equal(self.testobj, strict=True)) def test_equal_file_leading_perms(self): # testobj with leading_perms self.testobj = FileRule( '/foo', 'rw', 'ix', '/bar', False, False, True) self.assertTrue(self.obj.is_equal(self.testobj, strict=False)) self.assertFalse(self.obj.is_equal(self.testobj, strict=True)) def test_covered_anyperm_1(self): self.obj = FileRule( '/foo', 'rw', None, '/bar', False, False, False) self.testobj = FileRule( '/foo', 'rw', FileRule.ANY_EXEC, '/bar', False, False, False) self.assertFalse(self.obj.is_covered(self.testobj)) self.assertFalse(self.obj.is_equal(self.testobj, strict=False)) self.assertFalse(self.obj.is_equal(self.testobj, strict=True)) def test_covered_anyperm_2(self): self.testobj = FileRule( '/foo', 'rw', FileRule.ANY_EXEC,'/bar', False, False, False) self.assertTrue(self.obj.is_covered(self.testobj)) self.assertFalse(self.obj.is_equal(self.testobj, strict=False)) self.assertFalse(self.obj.is_equal(self.testobj, strict=True)) def test_covered_anyperm_3(self): # make sure a different exec target gets ignored with ANY_EXEC self.testobj = FileRule( '/foo', 'rw', FileRule.ANY_EXEC, '/xyz', False, False, False) self.assertTrue(self.obj.is_covered(self.testobj)) self.assertFalse(self.obj.is_equal(self.testobj, strict=False)) self.assertFalse(self.obj.is_equal(self.testobj, strict=True)) def test_covered_anyperm_4(self): # make sure a different exec target gets ignored with ANY_EXEC self.testobj = FileRule( '/foo', 'rw', FileRule.ANY_EXEC, FileRule.ALL, False, False, False) self.assertTrue(self.obj.is_covered(self.testobj)) self.assertFalse(self.obj.is_equal(self.testobj, strict=False)) self.assertFalse(self.obj.is_equal(self.testobj, strict=True)) def test_covered_anyperm_5(self): # even with ANY_EXEC, a different link target causes a mismatch self.testobj = FileRule( '/foo', 'rwl', FileRule.ANY_EXEC, '/xyz', False, False, False) self.assertFalse(self.obj.is_covered(self.testobj)) self.assertFalse(self.obj.is_equal(self.testobj, strict=False)) self.assertFalse(self.obj.is_equal(self.testobj, strict=True)) def test_covered_anyperm_6(self): # even with ANY_EXEC, a different link target causes a mismatch self.testobj = FileRule( '/foo', 'rwl', FileRule.ANY_EXEC, FileRule.ALL, False, False, False) self.assertFalse(self.obj.is_covered(self.testobj)) self.assertFalse(self.obj.is_equal(self.testobj, strict=False)) self.assertFalse(self.obj.is_equal(self.testobj, strict=True)) def test_covered_anyperm_7(self): self.obj = FileRule( '/foo', 'rw', 'x', '/bar', False, False, False, deny=True) self.testobj = FileRule( '/foo', 'rw', FileRule.ANY_EXEC,'/bar', False, False, False) self.assertFalse(self.obj.is_covered(self.testobj)) self.assertTrue(self.obj.is_covered(self.testobj, check_allow_deny=False)) self.assertFalse(self.obj.is_equal(self.testobj, strict=False)) self.assertFalse(self.obj.is_equal(self.testobj, strict=True)) def test_borked_obj_is_covered_1(self): self.testobj.path = '' with self.assertRaises(AppArmorBug): self.obj.is_covered(self.testobj) def test_borked_obj_is_covered_2(self): self.testobj.perms = set() self.testobj.exec_perms = '' with self.assertRaises(AppArmorBug): self.obj.is_covered(self.testobj) def test_borked_obj_is_covered_3(self): self.testobj.target = '' with self.assertRaises(AppArmorBug): self.obj.is_covered(self.testobj) def test_invalid_is_covered(self): obj = FileRule.parse('file,') testobj = BaseRule() # different type with self.assertRaises(AppArmorBug): obj.is_covered(testobj) def test_invalid_is_equal(self): obj = FileRule.parse('file,') testobj = BaseRule() # different type with self.assertRaises(AppArmorBug): obj.is_equal(testobj) class FileSeverityTest(AATest): tests = [ ('/usr/bin/whatis ix,', 5), ('/etc ix,', 'unknown'), ('/dev/doublehit ix,', 0), ('/dev/doublehit rix,', 4), ('/dev/doublehit rwix,', 8), ('/dev/tty10 rwix,', 9), ('/var/adm/foo/** rix,', 3), ('/etc/apparmor/** r,', 6), ('/etc/** r,', 'unknown'), ('/usr/foo@bar r,', 'unknown'), # filename containing @ ('/home/foo@bar rw,', 6), # filename containing @ ('file,', 'unknown'), # bare file rule XXX should return maximum severity ] def _run_test(self, params, expected): sev_db = severity.Severity('severity.db', 'unknown') obj = FileRule.parse(params) rank = obj.severity(sev_db) self.assertEqual(rank, expected) class FileLogprofHeaderTest(AATest): tests = [ # log event old perms ALL / owner (['file,', set(), set() ], [ _('Path'), _('ALL'), _('New Mode'), _('ALL') ]), (['/foo r,', set(), set() ], [ _('Path'), '/foo', _('New Mode'), 'r' ]), (['file /bar Px -> foo,', set(), set() ], [ _('Path'), '/bar', _('New Mode'), 'Px -> foo' ]), (['deny file,', set(), set() ], [_('Qualifier'), 'deny', _('Path'), _('ALL'), _('New Mode'), _('ALL') ]), (['allow file /baz rwk,', set(), set() ], [_('Qualifier'), 'allow', _('Path'), '/baz', _('New Mode'), 'rwk' ]), (['audit file /foo mr,', set(), set() ], [_('Qualifier'), 'audit', _('Path'), '/foo', _('New Mode'), 'mr' ]), (['audit deny /foo wk,', set(), set() ], [_('Qualifier'), 'audit deny', _('Path'), '/foo', _('New Mode'), 'wk' ]), (['owner file /foo ix,', set(), set() ], [ _('Path'), '/foo', _('New Mode'), 'owner ix' ]), (['audit deny file /foo rlx -> /baz,', set(), set() ], [_('Qualifier'), 'audit deny', _('Path'), '/foo', _('New Mode'), 'rlx -> /baz' ]), (['/foo rw,', set('r'), set() ], [ _('Path'), '/foo', _('Old Mode'), _('r'), _('New Mode'), _('rw') ]), (['/foo rw,', set(), set('rw') ], [ _('Path'), '/foo', _('Old Mode'), _('owner rw'), _('New Mode'), _('rw') ]), (['/foo mrw,', set('r'), set('k') ], [ _('Path'), '/foo', _('Old Mode'), _('r + owner k'), _('New Mode'), _('mrw') ]), (['/foo mrw,', set('r'), set('rk') ], [ _('Path'), '/foo', _('Old Mode'), _('r + owner k'), _('New Mode'), _('mrw') ]), ] def _run_test(self, params, expected): obj = FileRule._parse(params[0]) if params[1] or params[2]: obj.original_perms = {'allow': { 'all': params[1], 'owner': params[2]}} self.assertEqual(obj.logprof_header(), expected) def test_empty_original_perms(self): obj = FileRule._parse('/foo rw,') obj.original_perms = {'allow': { 'all': set(), 'owner': set()}} self.assertEqual(obj.logprof_header(), [_('Path'), '/foo', _('New Mode'), _('rw')]) class FileEditHeaderTest(AATest): def _run_test(self, params, expected): rule_obj = FileRule.parse(params) self.assertEqual(rule_obj.can_edit, True) prompt, path_to_edit = rule_obj.edit_header() self.assertEqual(path_to_edit, expected) tests = [ ('/foo/bar/baz r,', '/foo/bar/baz'), ('/foo/**/baz r,', '/foo/**/baz'), ] def test_edit_header_bare_file(self): rule_obj = FileRule.parse('file,') self.assertEqual(rule_obj.can_edit, False) with self.assertRaises(AppArmorBug): rule_obj.edit_header() class FileValidateAndStoreEditTest(AATest): def _run_test(self, params, expected): rule_obj = FileRule('/foo/bar/baz', 'r', None, FileRule.ALL, False, False, False, log_event=True) self.assertEqual(rule_obj.validate_edit(params), expected) rule_obj.store_edit(params) self.assertEqual(rule_obj.get_raw(), '%s r,' % params) tests = [ # edited path match ('/foo/bar/baz', True), ('/foo/bar/*', True), ('/foo/bar/???', True), ('/foo/xy**', False), ('/foo/bar/baz/', False), ] def test_validate_not_a_path(self): rule_obj = FileRule.parse('/foo/bar/baz r,') with self.assertRaises(AppArmorException): rule_obj.validate_edit('foo/bar/baz') with self.assertRaises(AppArmorException): rule_obj.store_edit('foo/bar/baz') def test_validate_edit_bare_file(self): rule_obj = FileRule.parse('file,') self.assertEqual(rule_obj.can_edit, False) with self.assertRaises(AppArmorBug): rule_obj.validate_edit('/foo/bar') with self.assertRaises(AppArmorBug): rule_obj.store_edit('/foo/bar') ## --- tests for FileRuleset --- # class FileRulesTest(AATest): def test_empty_ruleset(self): ruleset = FileRuleset() ruleset_2 = FileRuleset() self.assertEqual([], ruleset.get_raw(2)) self.assertEqual([], ruleset.get_clean(2)) self.assertEqual([], ruleset_2.get_raw(2)) self.assertEqual([], ruleset_2.get_clean(2)) def test_ruleset_1(self): ruleset = FileRuleset() rules = [ ' file , ', ' file /foo rw,', ' file /bar r,', ] expected_raw = [ 'file ,', 'file /foo rw,', 'file /bar r,', '', ] expected_clean = [ 'file /bar r,', 'file /foo rw,', 'file,', '', ] deleted = 0 for rule in rules: deleted += ruleset.add(FileRule.parse(rule)) self.assertEqual(deleted, 0) self.assertEqual(expected_raw, ruleset.get_raw()) self.assertEqual(expected_clean, ruleset.get_clean()) def test_ruleset_2(self): ruleset = FileRuleset() rules = [ '/foo Px,', '/bar Cx -> bar_child ,', 'deny /asdf w,', ] expected_raw = [ ' /foo Px,', ' /bar Cx -> bar_child ,', ' deny /asdf w,', '', ] expected_clean = [ ' deny /asdf w,', '', ' /bar Cx -> bar_child,', ' /foo Px,', '', ] deleted = 0 for rule in rules: deleted += ruleset.add(FileRule.parse(rule)) self.assertEqual(deleted, 0) self.assertEqual(expected_raw, ruleset.get_raw(1)) self.assertEqual(expected_clean, ruleset.get_clean(1)) def test_ruleset_cleanup_add_1(self): ruleset = FileRuleset() rules = [ '/foo/bar r,', '/foo/baz rw,', '/foo/baz rwk,', ] rules_with_cleanup = [ '/foo/* r,', ] expected_raw = [ ' /foo/baz rw,', ' /foo/baz rwk,', ' /foo/* r,', '', ] expected_clean = [ ' /foo/* r,', ' /foo/baz rw,', ' /foo/baz rwk,', '', ] deleted = 0 for rule in rules: deleted += ruleset.add(FileRule.parse(rule)) self.assertEqual(deleted, 0) # rules[] are added without cleanup mode, so the superfluous '/foo/baz rw,' should be kept for rule in rules_with_cleanup: deleted += ruleset.add(FileRule.parse(rule), cleanup=True) self.assertEqual(deleted, 1) # rules_with_cleanup made '/foo/bar r,' superfluous self.assertEqual(expected_raw, ruleset.get_raw(1)) self.assertEqual(expected_clean, ruleset.get_clean(1)) #class FileDeleteTest(AATest): # pass class FileGetRulesForPath(AATest): tests = [ # path audit deny expected (('/etc/foo/dovecot.conf', False, False), ['/etc/foo/* r,', '/etc/foo/dovecot.conf rw,', '']), (('/etc/foo/foo.conf', False, False), ['/etc/foo/* r,', '']), (('/etc/foo/dovecot-database.conf.ext', False, False), ['/etc/foo/* r,', '/etc/foo/dovecot-database.conf.ext w,', '']), (('/etc/foo/auth.d/authfoo.conf', False, False), ['/etc/foo/{auth,conf}.d/*.conf r,','/etc/foo/{auth,conf}.d/authfoo.conf w,', '']), (('/etc/foo/dovecot-deny.conf', False, False), ['deny /etc/foo/dovecot-deny.conf r,', '', '/etc/foo/* r,', '']), (('/foo/bar', False, True ), [ ]), (('/etc/foo/dovecot-deny.conf', False, True ), ['deny /etc/foo/dovecot-deny.conf r,', '']), (('/etc/foo/foo.conf', False, True ), [ ]), (('/etc/foo/owner.conf', False, False), ['/etc/foo/* r,', 'owner /etc/foo/owner.conf w,', '']), ] def _run_test(self, params, expected): rules = [ '/etc/foo/* r,', '/etc/foo/dovecot.conf rw,', '/etc/foo/{auth,conf}.d/*.conf r,', '/etc/foo/{auth,conf}.d/authfoo.conf w,', '/etc/foo/dovecot-database.conf.ext w,', 'owner /etc/foo/owner.conf w,', 'deny /etc/foo/dovecot-deny.conf r,', ] ruleset = FileRuleset() for rule in rules: ruleset.add(FileRule.parse(rule)) matching = ruleset.get_rules_for_path(params[0], params[1], params[2]) self. assertEqual(matching.get_clean(), expected) class FileGetPermsForPath_1(AATest): tests = [ # path audit deny expected (('/etc/foo/dovecot.conf', False, False), {'allow': {'all': {'r', 'w'}, 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': {'/etc/foo/*', '/etc/foo/dovecot.conf' } }), (('/etc/foo/foo.conf', False, False), {'allow': {'all': {'r' }, 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': {'/etc/foo/*' } }), (('/etc/foo/dovecot-database.conf.ext', False, False), {'allow': {'all': {'r', 'w'}, 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': {'/etc/foo/*', '/etc/foo/dovecot-database.conf.ext' } }), (('/etc/foo/auth.d/authfoo.conf', False, False), {'allow': {'all': {'r', 'w'}, 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': {'/etc/foo/{auth,conf}.d/*.conf', '/etc/foo/{auth,conf}.d/authfoo.conf' } }), (('/etc/foo/dovecot-deny.conf', False, False), {'allow': {'all': {'r' }, 'owner': set() }, 'deny': {'all': {'r' }, 'owner': set() }, 'paths': {'/etc/foo/*', '/etc/foo/dovecot-deny.conf' } }), (('/foo/bar', False, True ), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': set() }), (('/etc/foo/dovecot-deny.conf', False, True ), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': {'r' }, 'owner': set() }, 'paths': {'/etc/foo/dovecot-deny.conf' } }), (('/etc/foo/foo.conf', False, True ), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': set() }), (('/usr/lib/dovecot/config', False, False), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': set() }), # exec perms are not honored by get_perms_for_path() ] def _run_test(self, params, expected): rules = [ '/etc/foo/* r,', '/etc/foo/dovecot.conf rw,', '/etc/foo/{auth,conf}.d/*.conf r,', '/etc/foo/{auth,conf}.d/authfoo.conf w,', '/etc/foo/dovecot-database.conf.ext w,', 'deny /etc/foo/dovecot-deny.conf r,', '/usr/lib/dovecot/config ix,', ] ruleset = FileRuleset() for rule in rules: ruleset.add(FileRule.parse(rule)) perms = ruleset.get_perms_for_path(params[0], params[1], params[2]) self. assertEqual(perms, expected) class FileGetPermsForPath_2(AATest): tests = [ # path audit deny expected (('/etc/foo/dovecot.conf', False, False), {'allow': {'all': FileRule.ALL, 'owner': set() }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': {'/etc/foo/*', '/etc/foo/dovecot.conf' } }), (('/etc/foo/dovecot.conf', True, False), {'allow': {'all': {'r', 'w'}, 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': {'/etc/foo/dovecot.conf' } }), (('/etc/foo/foo.conf', False, False), {'allow': {'all': FileRule.ALL, 'owner': set() }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': {'/etc/foo/*' } }), (('/etc/foo/dovecot-database.conf.ext', False, False), {'allow': {'all': FileRule.ALL, 'owner': set() }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': {'/etc/foo/*', '/etc/foo/dovecot-database.conf.ext' } }), (('/etc/foo/auth.d/authfoo.conf', False, False), {'allow': {'all': FileRule.ALL, 'owner': set() }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': {'/etc/foo/{auth,conf}.d/*.conf', '/etc/foo/{auth,conf}.d/authfoo.conf' } }), (('/etc/foo/auth.d/authfoo.conf', True, False), {'allow': {'all': {'w' }, 'owner': set() }, 'deny': {'all': set(), 'owner': set() }, 'paths': {'/etc/foo/{auth,conf}.d/authfoo.conf' } }), (('/etc/foo/dovecot-deny.conf', False, False), {'allow': {'all': FileRule.ALL, 'owner': set() }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': {'/etc/foo/*', '/etc/foo/dovecot-deny.conf' } }), (('/foo/bar', False, True ), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': set() }), (('/etc/foo/dovecot-deny.conf', False, True ), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': {'/etc/foo/dovecot-deny.conf' } }), (('/etc/foo/foo.conf', False, True ), {'allow': {'all': set(), 'owner': set() }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': set() }), # (('/etc/foo/owner.conf', False, True ), {'allow': {'all': set(), 'owner': {'w'} }, 'deny': {'all': FileRule.ALL, 'owner': set() }, 'paths': {'/etc/foo/owner.conf' } }), # XXX doen't work yet ] def _run_test(self, params, expected): rules = [ '/etc/foo/* r,', 'audit /etc/foo/dovecot.conf rw,', '/etc/foo/{auth,conf}.d/*.conf r,', 'audit /etc/foo/{auth,conf}.d/authfoo.conf w,', '/etc/foo/dovecot-database.conf.ext w,', 'deny /etc/foo/dovecot-deny.conf r,', 'file,', 'owner /etc/foo/owner.conf w,', 'deny file,', ] ruleset = FileRuleset() for rule in rules: ruleset.add(FileRule.parse(rule)) perms = ruleset.get_perms_for_path(params[0], params[1], params[2]) self. assertEqual(perms, expected) class FileGetExecRulesForPath_1(AATest): tests = [ ('/bin/foo', ['audit /bin/foo ix,', ''] ), ('/bin/bar', ['deny /bin/bar x,', ''] ), ('/foo', [] ), ] def _run_test(self, params, expected): rules = [ '/foo r,', 'audit /bin/foo ix,', '/bin/b* Px,', 'deny /bin/bar x,', ] ruleset = FileRuleset() for rule in rules: ruleset.add(FileRule.parse(rule)) perms = ruleset.get_exec_rules_for_path(params) matches = perms.get_clean() self. assertEqual(matches, expected) class FileGetExecRulesForPath_2(AATest): tests = [ ('/bin/foo', ['audit /bin/foo ix,', ''] ), ('/bin/bar', ['deny /bin/bar x,', '', '/bin/b* Px,', ''] ), ('/foo', [] ), ] def _run_test(self, params, expected): rules = [ '/foo r,', 'audit /bin/foo ix,', '/bin/b* Px,', 'deny /bin/bar x,', ] ruleset = FileRuleset() for rule in rules: ruleset.add(FileRule.parse(rule)) perms = ruleset.get_exec_rules_for_path(params, only_exact_matches=False) matches = perms.get_clean() self. assertEqual(matches, expected) class FileGetExecConflictRules_1(AATest): tests = [ ('/bin/foo ix,', ['/bin/foo Px,', ''] ), ('/bin/bar Px,', ['deny /bin/bar x,', '', '/bin/bar cx,', ''] ), ('/bin/bar cx,', ['deny /bin/bar x,','',] ), ('/bin/foo r,', [] ), ] def _run_test(self, params, expected): rules = [ '/foo r,', 'audit /bin/foo ix,', '/bin/foo Px,', '/bin/b* Px,', '/bin/bar cx,', 'deny /bin/bar x,', ] ruleset = FileRuleset() for rule in rules: ruleset.add(FileRule.parse(rule)) rule_obj = FileRule.parse(params) conflicts = ruleset.get_exec_conflict_rules(rule_obj) self. assertEqual(conflicts.get_clean(), expected) setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1) apparmor-2.13.3/utils/test/fake_ldd0000755000175000017500000000477013502024172015013 0ustar jjjj#!/usr/bin/python3 import sys if len(sys.argv) != 2: raise Exception('wrong number of arguments in fake_ldd') if sys.argv[1] in ['/AATest/bin/bash', '/bin/bash', '/usr/bin/bash']: print(' linux-vdso.so.1 (0x00007ffcf97f4000)') print(' libreadline.so.6 => /AATest/lib64/libreadline.so.6 (0x00007f2c41324000)') print(' libtinfo.so.6 => /AATest/lib64/libtinfo.so.6 (0x00007f2c410f9000)') print(' libdl.so.2 => /AATest/lib64/libdl.so.2 (0x00007f2c40ef5000)') print(' libc.so.6 => /AATest/lib64/libc.so.6 (0x00007f2c40b50000)') print(' /AATest/lib64/ld-linux-x86-64.so.2 (0x000055782c473000)') elif sys.argv[1] == '/AATest/lib64/ld-2.22.so': print(' linux-vdso.so.1 (0x00007ffcf97f4000)') elif sys.argv[1] == '/AATest/lib64/libc-2.22.so': print(' /AATest/lib64/ld-linux-x86-64.so.2 (0x0000556858473000)') print(' linux-vdso.so.1 (0x00007ffe98912000)') elif sys.argv[1] == '/AATest/lib64/libdl.so.2': print(' linux-vdso.so.1 (0x00007ffec2538000)') print(' libc.so.6 => /AATest/lib64/libc.so.6 (0x00007f8865346000)') print(' /AATest/lib64/ld-linux-x86-64.so.2 (0x0000560c3bcee000)') elif sys.argv[1] == '/AATest/lib64/libtinfo.so.6': print(' linux-vdso.so.1 (0x00007fff30518000)') print(' libc.so.6 => /AATest/lib64/libc.so.6 (0x00007fb6f2ea3000)') print(' /AATest/lib64/ld-linux-x86-64.so.2 (0x00005631fe8d3000)') elif sys.argv[1] == '/AATest/lib64/libreadline.so.6': print(' linux-vdso.so.1 (0x00007ffcb5b62000)') print(' libtinfo.so.6 => /AATest/lib64/libtinfo.so.6 (0x00007f2a4ed07000)') print(' libc.so.6 => /AATest/lib64/libc.so.6 (0x00007f2a4e961000)') print(' /AATest/lib64/ld-linux-x86-64.so.2 (0x000055f749c89000)') elif sys.argv[1] == '/AATest/lib64/ld-linux-x86-64.so.2': print(' statically linked') elif sys.argv[1] == '/AATest/lib64/libc.so.6': print(' /AATest/lib64/ld-linux-x86-64.so.2 (0x000055b65f7a9000)') print(' linux-vdso.so.1 (0x00007ffde132b000)') elif sys.argv[1] == '/AATest/sbin/ldconfig': print(' not a dynamic executable') sys.exit(1) # ldd exits with $? == 1 in this case elif sys.argv[1].startswith('/tmp/aa-test-'): # test file generated by test-aa.py print(' not a dynamic executable') elif sys.argv[1] == 'TEMPLATE': print('') print('') print('') else: raise Exception('unknown parameter in fake_ldd: %s' % sys.argv[1]) apparmor-2.13.3/utils/aa-status.80000644000175000017500000001515013502024375014347 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "AA-STATUS 8" .TH AA-STATUS 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa\-status \- display various information about the current AppArmor policy. .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-status\fR [option] .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBaa-status\fR will report various aspects of the current state of AppArmor confinement. By default, it displays the same information as if the \fI\-\-verbose\fR argument were given. A sample of what this looks like is: .PP .Vb 8 \& apparmor module is loaded. \& 110 profiles are loaded. \& 102 profiles are in enforce mode. \& 8 profiles are in complain mode. \& Out of 129 processes running: \& 13 processes have profiles defined. \& 8 processes have profiles in enforce mode. \& 5 processes have profiles in complain mode. .Ve .PP Other argument options are provided to report individual aspects, to support being used in scripts. .SH "OPTIONS" .IX Header "OPTIONS" \&\fBaa-status\fR accepts only one argument at a time out of: .IP "\-\-enabled" 4 .IX Item "--enabled" returns error code if AppArmor is not enabled. .IP "\-\-profiled" 4 .IX Item "--profiled" displays the number of loaded AppArmor policies. .IP "\-\-enforced" 4 .IX Item "--enforced" displays the number of loaded enforcing AppArmor policies. .IP "\-\-complaining" 4 .IX Item "--complaining" displays the number of loaded non-enforcing AppArmor policies. .IP "\-\-verbose" 4 .IX Item "--verbose" displays multiple data points about loaded AppArmor policy set (the default action if no arguments are given). .IP "\-\-json" 4 .IX Item "--json" displays multiple data points about loaded AppArmor policy set in a \s-1JSON\s0 format, fit for machine consumption. .IP "\-\-pretty\-json" 4 .IX Item "--pretty-json" same as \-\-json, formatted to be readable by humans as well as by machines. .IP "\-\-help" 4 .IX Item "--help" displays a short usage statement. .SH "EXIT STATUS" .IX Header "EXIT STATUS" Upon exiting, \fBaa-status\fR will set its exit status to the following values: .IP "\fB0\fR" 4 .IX Item "0" if apparmor is enabled and policy is loaded. .IP "\fB1\fR" 4 .IX Item "1" if apparmor is not enabled/loaded. .IP "\fB2\fR" 4 .IX Item "2" if apparmor is enabled but no policy is loaded. .IP "\fB3\fR" 4 .IX Item "3" if the apparmor control files aren't available under /sys/kernel/security/. .IP "\fB4\fR" 4 .IX Item "4" if the user running the script doesn't have enough privileges to read the apparmor control files. .SH "BUGS" .IX Header "BUGS" \&\fBaa-status\fR must be run as root to read the state of the loaded policy from the apparmor module. It uses the /proc filesystem to determine which processes are confined and so is susceptible to race conditions. .PP If you find any additional bugs, please report them at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7), \fIapparmor.d\fR\|(5), and . apparmor-2.13.3/utils/aa-complain.8.html0000644000175000017500000000443513502024376015576 0ustar jjjj
 

NAME

aa-complain - set an AppArmor security profile to complain mode.

SYNOPSIS

aa-complain <executable> [<executable> ...] [-d /path/to/profiles] [--no-reload]

OPTIONS

-d --dir /path/to/profiles

   Specifies where to look for the AppArmor security profile set.
   Defaults to /etc/apparmor.d.

--no-reload Do not reload the profile after modifying it.

DESCRIPTION

aa-complain is used to set the enforcement mode for one or more profiles to complain mode. In this mode security policy is not enforced but rather access violations are logged to the system log.

Note that 'deny' rules will be enforced even in complain mode.

BUGS

If you find any bugs, please report them at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7), apparmor.d(5), aa-enforce(1), aa-disable(1), aa_change_hat(2), and https://wiki.apparmor.net.

 
apparmor-2.13.3/utils/aa-remove-unknown.pod0000644000175000017500000000167213502024172016430 0ustar jjjj=pod =head1 NAME aa-remove-unknown - remove unknown AppArmor profiles =head1 SYNOPSIS B [option] =head1 DESCRIPTION B will inventory all profiles in /etc/apparmor.d/, compare that list to the profiles currently loaded into the kernel, and then remove all of the loaded profiles that were not found in /etc/apparmor.d/. It will also report the name of each profile that it removes on standard out. =head1 OPTIONS =over 4 =item -h, --help displays a short usage statement. =item -n dry run; only prints the names of profiles that would be removed =back =head1 EXAMPLES $ sudo ./aa-remove-unknown -n Would remove 'test//null-/usr/bin/whoami' Would remove 'test' $ sudo ./aa-remove-unknown Removing 'test//null-/usr/bin/whoami' Removing 'test' =head1 BUGS None. Please report any you find to Launchpad at L. =head1 SEE ALSO apparmor(7) =cut apparmor-2.13.3/utils/aa-disable.pod0000644000175000017500000000361413502024172015037 0ustar jjjj# This publication is intellectual property of Novell Inc. and Canonical # Ltd. Its contents can be duplicated, either in part or in whole, provided # that a copyright label is visibly located on each copy. # # All information found in this book has been compiled with utmost # attention to detail. However, this does not guarantee complete accuracy. # Neither SUSE LINUX GmbH, Canonical Ltd, the authors, nor the translators # shall be held liable for possible errors or the consequences thereof. # # Many of the software and hardware descriptions cited in this book # are registered trademarks. All trade names are subject to copyright # restrictions and may be registered trade marks. SUSE LINUX GmbH # and Canonical Ltd. essentially adhere to the manufacturer's spelling. # # Names of products and trademarks appearing in this book (with or without # specific notation) are likewise subject to trademark and trade protection # laws and may thus fall under copyright restrictions. # =pod =head1 NAME aa-disable - disable an AppArmor security profile =head1 SYNOPSIS BexecutableE> [IexecutableE> ...] [I<-d /path/to/profiles>] [I<--no-reload>] [I<-r>]> =head1 OPTIONS B<-d --dir /path/to/profiles> Specifies where to look for the AppArmor security profile set. Defaults to /etc/apparmor.d. B<--no-reload> Do not unreload the profile after modifying it. =head1 DESCRIPTION B is used to I one or more profiles. This command will unload the profile from the kernel and prevent the profile from being loaded on AppArmor startup. The I and I utilities may be used to to change this behavior. =head1 BUGS If you find any bugs, please report them at L. =head1 SEE ALSO apparmor(7), apparmor.d(5), aa-enforce(1), aa-complain(1), aa_change_hat(2), and L. =cut apparmor-2.13.3/utils/aa-unconfined0000755000175000017500000001400513502024172015002 0ustar jjjj#! /usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2016 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import argparse import os import re import subprocess import sys import apparmor.aa as aa import apparmor.ui as ui import apparmor.common # setup exception handling from apparmor.fail import enable_aa_exception_handler enable_aa_exception_handler() # setup module translations from apparmor.translations import init_translation _ = init_translation() parser = argparse.ArgumentParser(description=_("Lists unconfined processes having tcp or udp ports")) parser.add_argument("--paranoid", action="store_true", help=_("scan all processes from /proc")) bin_group = parser.add_mutually_exclusive_group() bin_group.add_argument("--with-ss", action='store_true', help=_("use ss(8) to find listening processes (default)")) bin_group.add_argument("--with-netstat", action='store_true', help=_("use netstat(8) to find listening processes")) args = parser.parse_args() paranoid = args.paranoid aa.init_aa() aa_mountpoint = aa.check_for_apparmor() if not aa_mountpoint: raise aa.AppArmorException(_("It seems AppArmor was not started. Please enable AppArmor and try again.")) def get_all_pids(): '''Return a set of all pids via walking /proc''' return set(filter(lambda x: re.search(r"^\d+$", x), aa.get_subdirectories("/proc"))) def get_pids_ss(ss='ss'): '''Get a set of pids listening on network sockets via ss(8)''' regex_lines = re.compile(r"^(tcp|udp|raw|p_dgr)\s.+\s+users:(?P\(\(.*\)\))$") regex_users_pids = re.compile(r'(\("[^"]+",(pid=)?(\d+),[^)]+\))') pids = set() my_env = os.environ.copy() my_env['LANG'] = 'C' my_env['PATH'] = '/bin:/usr/bin:/sbin:/usr/sbin' for family in ['inet', 'inet6', 'link']: cmd = [ss, '-nlp', '--family', family] if sys.version_info < (3, 0): output = subprocess.check_output(cmd, shell=False, env=my_env).split("\n") else: # Python3 needs to translate a stream of bytes to string with specified encoding output = str(subprocess.check_output(cmd, shell=False, env=my_env), encoding='utf8').split("\n") for line in output: match = regex_lines.search(line.strip()) if match: users = match.group('users') for (_, _, pid) in regex_users_pids.findall(users): pids.add(pid) return pids def get_pids_netstat(netstat='netstat'): '''Get a set of pids listening on network sockets via netstat(8)''' regex_tcp_udp = re.compile(r"^(tcp|udp|raw)6?\s+\d+\s+\d+\s+\S+\:(\d+)\s+\S+\:(\*|\d+)\s+(LISTEN|\d+|\s+)\s+(?P\d+)\/(\S+)") cmd = [netstat, '-nlp', '--protocol', 'inet,inet6'] my_env = os.environ.copy() my_env['LANG'] = 'C' my_env['PATH'] = '/bin:/usr/bin:/sbin:/usr/sbin' if sys.version_info < (3, 0): output = subprocess.check_output(cmd, shell=False, env=my_env).split("\n") else: # Python3 needs to translate a stream of bytes to string with specified encoding output = str(subprocess.check_output(cmd, shell=False, env=my_env), encoding='utf8').split("\n") pids = set() for line in output: match = regex_tcp_udp.search(line) if match: pids.add(match.group('pid')) return pids pids = set() if paranoid: pids = get_all_pids() elif args.with_ss or (not args.with_netstat and (os.path.exists('/bin/ss') or os.path.exists('/usr/bin/ss'))): pids = get_pids_ss() else: pids = get_pids_netstat() for pid in sorted(map(int, pids)): try: prog = os.readlink("/proc/%s/exe" % pid) except OSError: continue attr = None if os.path.exists("/proc/%s/attr/current" % pid): with apparmor.common.open_file_read("/proc/%s/attr/current" % pid) as current: for line in current: line = line.strip() if line.endswith(' (complain)', 1) or line.endswith(' (enforce)', 1): # enforce at least one char as profile name attr = line pname = None cmdline = None with apparmor.common.open_file_read("/proc/%s/cmdline" % pid) as cmd: cmdline = cmd.readlines()[0] pname = cmdline.split("\0")[0] if '/' in pname and pname != prog: pname = "(%s)" % pname else: pname = "" regex_interpreter = re.compile(r"^(/usr)?/bin/(python|perl|bash|dash|sh)$") if not attr: if regex_interpreter.search(prog): cmdline = re.sub(r"\x00", " ", cmdline) cmdline = re.sub(r"\s+$", "", cmdline).strip() ui.UI_Info(_("%(pid)s %(program)s (%(commandline)s) not confined") % {'pid': pid, 'program': prog, 'commandline': cmdline}) else: if pname and pname[-1] == ')': pname = ' ' + pname ui.UI_Info(_("%(pid)s %(program)s%(pname)s not confined") % {'pid': pid, 'program': prog, 'pname': pname}) else: if regex_interpreter.search(prog): cmdline = re.sub(r"\0", " ", cmdline) cmdline = re.sub(r"\s+$", "", cmdline).strip() ui.UI_Info(_("%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'") % {'pid': pid, 'program': prog, 'commandline': cmdline, 'attribute': attr}) else: if pname and pname[-1] == ')': pname = ' ' + pname ui.UI_Info(_("%(pid)s %(program)s%(pname)s confined by '%(attribute)s'") % {'pid': pid, 'program': prog, 'pname': pname, 'attribute': attr}) apparmor-2.13.3/utils/aa-sandbox0000755000175000017500000000220413502024172014306 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2012 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import apparmor.sandbox from apparmor.common import error import optparse import sys # setup exception handling from apparmor.fail import enable_aa_exception_handler enable_aa_exception_handler() if __name__ == "__main__": argv = sys.argv parser = optparse.OptionParser() apparmor.easyprof.add_parser_policy_args(parser) (opt, args) = apparmor.sandbox.parse_args(sys.argv, parser) if len(args) < 1: error("Must specify binary") binary = args[0] if not apparmor.sandbox.check_requirements(binary): sys.exit(1) if opt.withx: rc, report = apparmor.sandbox.run_xsandbox(args, opt) else: rc, report = apparmor.sandbox.run_sandbox(args, opt) apparmor.common.msg(report) sys.exit(rc) apparmor-2.13.3/utils/aa-disable.8.html0000644000175000017500000000441213502024376015372 0ustar jjjj
 

NAME

aa-disable - disable an AppArmor security profile

SYNOPSIS

aa-disable <executable> [<executable> ...] [-d /path/to/profiles] [--no-reload] [-r]

OPTIONS

-d --dir /path/to/profiles

   Specifies where to look for the AppArmor security profile set.
   Defaults to /etc/apparmor.d.

--no-reload Do not unreload the profile after modifying it.

DESCRIPTION

aa-disable is used to disable one or more profiles. This command will unload the profile from the kernel and prevent the profile from being loaded on AppArmor startup. The aa-enforce and aa-complain utilities may be used to to change this behavior.

BUGS

If you find any bugs, please report them at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7), apparmor.d(5), aa-enforce(1), aa-complain(1), aa_change_hat(2), and https://wiki.apparmor.net.

 
apparmor-2.13.3/utils/aa-sandbox.pod0000644000175000017500000001424213502024172015071 0ustar jjjj# This publication is intellectual property of Canonical Ltd. Its contents # can be duplicated, either in part or in whole, provided that a copyright # label is visibly located on each copy. # # All information found in this book has been compiled with utmost # attention to detail. However, this does not guarantee complete accuracy. # Neither Canonical Ltd, the authors, nor the translators shall be held # liable for possible errors or the consequences thereof. # # Many of the software and hardware descriptions cited in this book # are registered trademarks. All trade names are subject to copyright # restrictions and may be registered trade marks. Canonical Ltd # essentially adheres to the manufacturer's spelling. # # Names of products and trademarks appearing in this book (with or without # specific notation) are likewise subject to trademark and trade protection # laws and may thus fall under copyright restrictions. # =pod =head1 NAME aa-sandbox - AppArmor sandboxing =head1 SYNOPSIS B [option] Epath to binaryE =head1 DESCRIPTION B provides a mechanism for sandboxing an application using an existing profile or via dynamic profile generation. Please note that while this tool can help with quickly confining an application, its utility is dependent on the quality of the templates, policy groups and abstractions used. Also, this tool may create policy which is less restrictive than creating policy by hand or with B and B. =head1 OPTIONS B accepts the following arguments: =over 4 =item -t TEMPLATE, --template=TEMPLATE Specify the template used to generate a profile. May specify either a system template or a filename for the template to use. If not specified, uses B or B when B<-X> is specified. See aa-easyprof(8) for details. Privileged access is required to load the dynamically generated profile (B will prompt for a password). =item -p POLICYGROUPS, --policy-groups=POLICYGROUPS Specify POLICYGROUPS as a comma-separated list of policy groups. See aa-easyprof(8) for more information on POLICYGROUPS. =item -a ABSTRACTIONS, --abstractions=ABSTRACTIONS Specify ABSTRACTIONS as a comma-separated list of AppArmor abstractions. AppArmor abstractions are located in /etc/apparmor.d/abstractions. See apparmor.d(5) for details. =item -r PATH, --read-path=PATH Specify a PATH to allow reads. May be specified multiple times. If the PATH ends in a '/', then PATH is treated as a directory and reads are allowed to all files under this directory. Can optionally use '/*' at the end of the PATH to only allow reads to files directly in PATH. =item -w PATH, --write-dir=PATH Like --read-path but also allow writes in addition to reads. =item --profile=PROFILE Instead of generating a dynamic profile, specify an existing, loaded profile. This does not require privileged access. =item -X, --with-x Run the sandboxed application in an isolated X server. =item --with-xauthority=XAUTHORITY Specify an Xauthority file to use rather than a dynamically generated one. This is particularly useful in combination with --profile. This option must be used with care to not allow too much access to the sandboxed application. In particular, the profile specified with --profile must add a rule to deny access to ~/.Xauthority for X sandboxing to be effective. Eg: audit deny @{HOME}/.Xauthority mrwlk, =item --with-xserver=XSERVER Choose the nested XSERVER to use. Supported servers are: B (the default), B and B. xpra uses the Xvfb(1) virtual framebuffer X server while xpra3d uses the Xorg(1) server with the Xdummy (dummy_drv.so) driver. =item --with-clipboard Allow access to the clipboard when using B or B. =item --with-xephyr-geometry=GEOMETRY The starting geometry for the Xephyr(1) server to use. =back =head1 EXAMPLES Use the existing system profile 'firefox' to sandbox /usr/bin/firefox: $ aa-sandbox -X --profile=firefox /usr/bin/firefox Sandbox xeyes: $ aa-sandbox -X /usr/bin/xeyes Sandbox glxgears: $ aa-sandbox -X --with-xserver=xpra3d /usr/bin/glxgears Sandbox uptime: $ aa-sandbox --read-path="/proc/*" /usr/bin/uptime =head1 NOTES B currently relies on Xsecurity rules based on Xauthority. As such, xhost access controls need to be enabled and server interpreted values for localuser must be removed. One way of achieving this is adding a late running Xsession(5) script of the form: # Create an Xauthority file if it doesn't exist [ ! -f "$HOME/.Xauthority" ] && [ -x /usr/bin/xauth ] && xauth generate :0 . trusted > /dev/null # Default to the Xauthority file [ -f "$HOME/.Xauthority" ] && [ -x /usr/bin/xhost ] && [ -x /usr/bin/id ] && xhost -si:localuser:`id -un` > /dev/null After adding the above, it is recommended you remove the existing ~/.Xauthority file, then restart your session. =head1 KNOWN LIMITATIONS While B may be useful in certain situations, there are a number of limitations regarding both confinement and usability: =over =item * As mentioned, the quality of the template or the specified profile directly affects the application's confinement. =item * DBus system access is all or nothing and DBus session access is unconditionally allowed. =item * No environment filtering is performed. =item * X server usage has not been fully audited (though simple attacks are believed to be protected against when the system is properly setup. See B, above). =item * Using a nested X server for each application is expensive. =item * Only the old X cursor is available with B and B. =item * The Ubuntu global menu is not currently supported. Gtk and Qt applications should display the non-global menu by default, but applications like Firefox and Thunderbird should be adjusted to disable the global menu. =item * Xpra does not handle screen resizing when hotplugging monitors gracefully. Restarting the sandbox will resolve the issue. =back =head1 BUGS If you find any bugs, please report them to Launchpad at L. =head1 SEE ALSO apparmor(7) apparmor.d(5) aa-easyprof(8) Xorg(1) Xecurity(7) xpra(1) Xvfb(1) Xephyr(1) =cut apparmor-2.13.3/utils/aa-complain0000755000175000017500000000263613502024172014463 0ustar jjjj#! /usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import argparse import apparmor.tools # setup exception handling from apparmor.fail import enable_aa_exception_handler enable_aa_exception_handler() # setup module translations from apparmor.translations import init_translation _ = init_translation() parser = argparse.ArgumentParser(description=_('Switch the given program to complain mode')) parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) parser.add_argument('program', type=str, nargs='+', help=_('name of program')) parser.add_argument('--no-reload', dest='do_reload', action='store_false', default=True, help=_('Do not reload the profile after modifying it')) args = parser.parse_args() tool = apparmor.tools.aa_tools('complain', args) #print(args) tool.cmd_complain() apparmor-2.13.3/utils/aa-remove-unknown.80000644000175000017500000001171513502024375016021 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "AA-REMOVE-UNKNOWN 8" .TH AA-REMOVE-UNKNOWN 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa\-remove\-unknown \- remove unknown AppArmor profiles .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-remove-unknown\fR [option] .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBaa-remove-unknown\fR will inventory all profiles in /etc/apparmor.d/, compare that list to the profiles currently loaded into the kernel, and then remove all of the loaded profiles that were not found in /etc/apparmor.d/. It will also report the name of each profile that it removes on standard out. .SH "OPTIONS" .IX Header "OPTIONS" .IP "\-h, \-\-help" 4 .IX Item "-h, --help" displays a short usage statement. .IP "\-n" 4 .IX Item "-n" dry run; only prints the names of profiles that would be removed .SH "EXAMPLES" .IX Header "EXAMPLES" .Vb 3 \& $ sudo ./aa\-remove\-unknown \-n \& Would remove \*(Aqtest//null\-/usr/bin/whoami\*(Aq \& Would remove \*(Aqtest\*(Aq \& \& $ sudo ./aa\-remove\-unknown \& Removing \*(Aqtest//null\-/usr/bin/whoami\*(Aq \& Removing \*(Aqtest\*(Aq .Ve .SH "BUGS" .IX Header "BUGS" None. Please report any you find to Launchpad at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7) apparmor-2.13.3/utils/vim/0000755000175000017500000000000013502024172013140 5ustar jjjjapparmor-2.13.3/utils/vim/apparmor.vim.pod0000644000175000017500000000366713502024172016273 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, # 2008, 2009 # NOVELL (All rights reserved) # # Copyright (c) 2010 - 2012 # Canonical Ltd. (All rights reserved) # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Canonical, Ltd. # ---------------------------------------------------------------------- =pod =head1 NAME apparmor.vim - vim syntax highlighting file for AppArmor profiles =head1 SYNOPSIS Your system may be configured to automatically use syntax highlighting for installed AppArmor policies. If not, you can enable syntax highlighting in a specific vim session by performing: :set syntax=apparmor =head1 DESCRIPTION B provides syntax highlighting rules for the vim(1) text editor; the rules provide an easy visual method to inspect AppArmor profiles for syntax correctness and semantics. The colors indicate the relative severity of granting a specific set of privileges. Ranking access with colors is necessarily generic and vague, but it may help you understand your profiles better. =head1 BUGS B does not properly detect dark versus light backgrounds. Patches accepted. If you find any bugs, please report them at L. =head1 SEE ALSO vim(1), apparmor(7), apparmor.d(5), aa_change_hat(2), and L. =cut apparmor-2.13.3/utils/vim/apparmor.vim.in0000644000175000017500000002265113502024172016111 0ustar jjjj" ---------------------------------------------------------------------- " Copyright (c) 2005 Novell, Inc. All Rights Reserved. " Copyright (c) 2006-2012 Christian Boltz. All Rights Reserved. " " This program is free software; you can redistribute it and/or " modify it under the terms of version 2 of the GNU General Public " License as published by the Free Software Foundation. " " This program is distributed in the hope that it will be useful, " but WITHOUT ANY WARRANTY; without even the implied warranty of " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " GNU General Public License for more details. " " You should have received a copy of the GNU General Public License " along with this program; if not, contact Novell, Inc. " " To contact Novell about this file by physical or electronic mail, " you may find current contact information at www.novell.com. " " To contact Christian Boltz about this file by physical or electronic " mail, you may find current contact information at www.cboltz.de/en/kontakt. " " If you want to report a bug via bugzilla.novell.com, please assign it " to suse-beta[AT]cboltz.de (replace [AT] with @). " ---------------------------------------------------------------------- " " stick this file into ~/.vim/syntax/ and add these commands into your .vimrc " to have vim automagically use this syntax file for these directories: " " autocmd BufNewFile,BufRead /etc/apparmor.d/* set syntax=apparmor " autocmd BufNewFile,BufRead /usr/share/apparmor/extra-profiles/* set syntax=apparmor " profiles are case sensitive syntax case match " color setup... " adjust colors according to the background " switching colors depending on the background color doesn't work " unfortunately, so we use colors that work with light and dark background. " Patches welcome ;-) "if &background == "light" " light background hi sdProfileName ctermfg=lightblue hi sdHatName ctermfg=darkblue hi sdExtHat ctermfg=darkblue " hi sdComment2 ctermfg=darkblue hi sdGlob ctermfg=darkmagenta hi sdAlias ctermfg=darkmagenta hi sdEntryWriteExec ctermfg=black ctermbg=yellow hi sdEntryUX ctermfg=darkred cterm=underline hi sdEntryUXe ctermfg=darkred hi sdEntryIX ctermfg=darkcyan hi sdEntryM ctermfg=darkcyan hi sdEntryPX ctermfg=darkgreen cterm=underline hi sdEntryPXe ctermfg=darkgreen hi sdEntryW ctermfg=darkyellow hi sdCap ctermfg=lightblue hi sdSetCap ctermfg=black ctermbg=yellow hi sdNetwork ctermfg=lightblue hi sdNetworkDanger ctermfg=darkred hi sdCapKey cterm=underline ctermfg=lightblue hi sdCapDanger ctermfg=darkred hi sdRLimit ctermfg=lightblue hi def link sdEntryR Normal hi def link sdEntryK Normal hi def link sdFlags Normal hi sdEntryChangeProfile ctermfg=darkgreen cterm=underline "else " dark background " hi sdProfileName ctermfg=white " hi sdHatName ctermfg=white " hi sdGlob ctermfg=magenta " hi sdEntryWriteExec ctermfg=black ctermbg=yellow " hi sdEntryUX ctermfg=red cterm=underline " hi sdEntryUXe ctermfg=red " hi sdEntryIX ctermfg=cyan " hi sdEntryM ctermfg=cyan " hi sdEntryPX ctermfg=green cterm=underline " hi sdEntryPXe ctermfg=green " hi sdEntryW ctermfg=yellow " hi sdCap ctermfg=lightblue " hi sdCapKey cterm=underline ctermfg=lightblue " hi def link sdEntryR Normal " hi def link sdFlags Normal " hi sdCapDanger ctermfg=red "endif hi def link sdInclude Include high def link sdComment Comment "high def link sdComment2 Comment high def link sdFlagKey TODO high def link sdError ErrorMsg " always sync from the start. should be relatively quick since we don't have " that many rules and profiles shouldn't be _extremely_ large... syn sync fromstart syn keyword sdFlagKey complain debug " highlight invalid syntax syn match sdError /{/ contained syn match sdError /}/ syn match sdError /^.*$/ contains=sdComment "highlight all non-valid lines as error " TODO: do not mark lines containing only whitespace as error " TODO: the sdGlob pattern is not anchored with ^ and $, so it matches all lines matching ^@{...}.* " This allows incorrect lines also and should be checked better. " This also (accidently ;-) includes variable definitions (@{FOO}=/bar) " TODO: make a separate pattern for variable definitions, then mark sdGlob as contained syn match sdGlob /\v\?|\*|\{.*,.*\}|[[^\]]\+\]|\@\{[a-zA-Z][a-zA-Z0-9_]*\}/ syn match sdAlias /\v^alias\s+@@FILENAME@@\s+-\>\s+@@FILENAME@@@@EOL@@/ contains=sdGlob,sdComment " syn match sdComment /#.*/ syn cluster sdEntry contains=sdEntryWriteExec,sdEntryR,sdEntryW,sdEntryIX,sdEntryPX,sdEntryPXe,sdEntryUX,sdEntryUXe,sdEntryM,sdCap,sdSetCap,sdExtHat,sdRLimit,sdNetwork,sdNetworkDanger,sdEntryChangeProfile " TODO: support audit and deny keywords for all rules (not only for files) " TODO: higlight audit and deny keywords everywhere " Capability line " normal capabilities - really keep this list? syn match sdCap should be enough... (difference: sdCapKey words would loose underlining) syn keyword sdCapKey @@sdKapKey@@ " dangerous capabilities - highlighted separately syn keyword sdCapDanger @@sdKapKeyDanger@@ " full line. Keywords are from sdCapKey + sdCapDanger syn match sdCap /\v^\s*@@auditdeny@@capability\s+((@@sdKapKeyRegex@@)\s+)*(@@sdKapKeyRegex@@)@@EOL@@/ contains=sdCapKey,sdCapDanger,sdComment nextgroup=@sdEntry,sdComment,sdError,sdInclude " all capabilities ('capability' without any keyword) syn match sdCapDanger /\v^\s*@@auditdeny@@capability@@EOL@@/ contains=sdComment nextgroup=@sdEntry,sdComment,sdError,sdInclude " Network line " Syntax: network domain (inet, ...) type (stream, ...) protocol (tcp, ...) " TODO: 'owner' isn't supported, but will be (JJ, 2011-01-11) syn match sdNetwork /\v^\s*@@auditdeny@@network(\s+(@@sdNetworkProto@@))?(\s+(stream|dgram|seqpacket|rdm|packet))?(@@sdNetworkType@@)?@@EOL@@/ contains=sdComment nextgroup=@sdEntry,sdComment,sdError,sdInclude " network rules containing 'raw' syn match sdNetworkDanger /\v^\s*@@auditdeny@@network(\s+(@@sdNetworkProto@@))?(\s+(raw))(@@sdNetworkType@@)?@@EOL@@/ contains=sdComment nextgroup=@sdEntry,sdComment,sdError,sdInclude " 'all networking' includes raw -> mark as dangerous syn match sdNetworkDanger /\v^\s*@@auditdeny@@network@@EOL@@/ contains=sdComment nextgroup=@sdEntry,sdComment,sdError,sdInclude " Change Profile syn match sdEntryChangeProfile /\v^\s*@@auditdeny@@change_profile\s+(safe\s+[/@]\S+|unsafe\s+[/@]\S+|[/@]\S+)?\s*(-\>\s*\S+)?@@EOL@@/ contains=sdGlob,sdComment nextgroup=@sdEntry,sdComment,sdError,sdInclude " bare change_profile rule syn match sdEntryChangeProfile /\v^\s*@@auditdeny@@change_profile@@EOL@@/ contains=sdComment nextgroup=@sdEntry,sdComment,sdError,sdInclude " rlimit " TODO: audit and deny support will be added (JJ, 2011-01-11) " "syn match sdRLimit /\v^\s*rlimit\s+()@@EOL@@/ contains=sdComment syn match sdRLimit /\v^\s*set\s+rlimit\s+(nofile|ofile|nproc|rtprio)\s+\<\=\s+[0-9]+@@EOL@@/ contains=sdComment syn match sdRLimit /\v^\s*set\s+rlimit\s+(locks|sigpending)\s+\<\=\s+[0-9]+@@EOL@@/ contains=sdComment syn match sdRLimit /\v^\s*set\s+rlimit\s+(fsize|data|stack|core|rss|as|memlock|msgqueue)\s+\<\=\s+[0-9]+([KMG]B)?@@EOL@@/ contains=sdComment syn match sdRLimit /\v^\s*set\s+rlimit\s+nice\s+\<\=\s+(-1?[0-9]|-20|1?[0-9])@@EOL@@/ contains=sdComment syn match sdRLimit /\v^\s*set\s+rlimit\s+cpu\s+\<\=\s+[0-9]+(seconds|minutes|hours|days)?@@EOL@@/ contains=sdComment syn match sdRLimit /\v^\s*set\s+rlimit\s+rttime\s+\<\=\s+[0-9]+(ms|seconds|minutes)?@@EOL@@/ contains=sdComment syn match sdRLimit /\v^\s*set\s+rlimit\s+(cpu|rttime|nofile|nproc|rtprio|locks|sigpending|fsize|data|stack|core|rss|as|memlock|msgqueue|nice)\s+\<\=\s+infinity@@EOL@@/ contains=sdComment " link rules syn match sdEntryW /\v^\s+@@auditdenyowner@@link\s+(subset\s+)?@@FILENAME@@\s+-\>\s+@@FILENAME@@@@EOL@@/ contains=sdGlob,sdComment syn match sdExtHat /\v^\s+(\^|hat\s+|profile\s+)\S+@@EOL@@/ contains=sdComment " hat without {...} syn match sdProfileName /\v^((profile\s+)?\/\S+|profile\s+([a-zA-Z0-9]\S*\s)?\S+)\s+@@flags@@=\{/ contains=sdProfileStart,sdHatName,sdFlags,sdComment,sdGlob syn match sdProfileStart /{/ contained syn match sdProfileEnd /^}\s*(#.*)?$/ contained " TODO: syn region does not (yet?) allow usage of comment in end= " TODO: Removing the $ mark from end= will allow non-comments also :-( syn match sdHatName /\v^\s+(\^|hat\s+|profile\s+)\S+\s+@@flags@@=\{/ contains=sdProfileStart,sdFlags,sdComment syn match sdHatStart /{/ contained syn match sdHatEnd /}/ contained " TODO: allow comments + [same as for syn match sdProfileEnd] syn match sdFlags /\v@@flags@@/ contained contains=sdFlagKey syn match sdComment /\s*#.*$/ " NOTE: contains=sdComment changes #include highlighting to comment color. " NOTE: Comment highlighting still works without contains=sdComment. syn match sdInclude /\s*#include\s<\S*>/ " TODO: doesn't check until $ syn match sdInclude /\s*include\s<\S*>/ " TODO: doesn't check until $ " basic profile block... " \s+ does not work in end=, therefore using \s\s* syn region Normal start=/\v^(profile\s+)?\S+\s+@@flags@@=\{/ matchgroup=sdProfileEnd end=/^}\s*$/ contains=sdProfileName,Hat,@sdEntry,sdComment,sdError,sdInclude syn region Hat start=/\v^\s+(\^|hat\s+|profile\s+)\S+\s+@@flags@@=\{/ matchgroup=sdHatEnd end=/^\s\s*}\s*$/ contains=sdHatName,@sdEntry,sdComment,sdError,sdInclude " file permissions apparmor-2.13.3/utils/vim/Makefile0000644000175000017500000000120513502024172014576 0ustar jjjjCOMMONDIR=../../common/ all: include $(COMMONDIR)/Make.rules MANPAGES=apparmor.vim.5 VIM_INSTALL_PATH=${DESTDIR}/usr/share/apparmor all: apparmor.vim manpages htmlmanpages apparmor.vim: apparmor.vim.in Makefile create-apparmor.vim.py ${PYTHON} create-apparmor.vim.py > apparmor.vim manpages: $(MANPAGES) htmlmanpages: $(HTMLMANPAGES) install: apparmor.vim manpages install -d $(VIM_INSTALL_PATH) install -m 644 $< $(VIM_INSTALL_PATH) $(MAKE) install_manpages DESTDIR=${DESTDIR} .PHONY: check check: check_pod_files #Testing with all pythons $(call pyalldo, create-apparmor.vim.py > /dev/null) clean: pod_clean rm -f apparmor.vim apparmor-2.13.3/utils/vim/create-apparmor.vim.py0000644000175000017500000001712413502024172017373 0ustar jjjj#!/usr/bin/python # # Copyright (C) 2012 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # Written by Steve Beattie , based on work by # Christian Boltz from __future__ import with_statement import re import subprocess import sys # dangerous capabilities danger_caps = ["audit_control", "audit_write", "mac_override", "mac_admin", "set_fcap", "sys_admin", "sys_module", "sys_rawio"] def cmd(command, input=None, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, stdin=None, timeout=None): '''Try to execute given command (array) and return its stdout, or return a textual error if it failed.''' try: sp = subprocess.Popen(command, stdin=stdin, stdout=stdout, stderr=stderr, close_fds=True, universal_newlines=True) except OSError as ex: return [127, str(ex)] out, outerr = sp.communicate(input) # Handle redirection of stdout if out is None: out = '' # Handle redirection of stderr if outerr is None: outerr = '' return [sp.returncode, out + outerr] # get capabilities list (rc, output) = cmd(['make', '-s', '--no-print-directory', 'list_capabilities']) if rc != 0: sys.stderr.write("make list_capabilities failed: " + output) exit(rc) capabilities = re.sub('CAP_', '', output.strip()).lower().split(" ") benign_caps = [] for cap in capabilities: if cap not in danger_caps: benign_caps.append(cap) # get network protos list (rc, output) = cmd(['make', '-s', '--no-print-directory', 'list_af_names']) if rc != 0: sys.stderr.write("make list_af_names failed: " + output) exit(rc) af_names = [] af_pairs = re.sub('AF_', '', output.strip()).lower().split(",") for af_pair in af_pairs: af_name = af_pair.lstrip().split(" ")[0] # skip max af name definition if len(af_name) > 0 and af_name != "max": af_names.append(af_name) # TODO: does a "debug" flag exist? Listed in apparmor.vim.in sdFlagKey, # but not in aa_flags... # -> currently (2011-01-11) not, but might come back aa_network_types = r'\s+tcp|\s+udp|\s+icmp' aa_flags = ['complain', 'audit', 'attach_disconnected', 'no_attach_disconnected', 'chroot_attach', 'chroot_no_attach', 'chroot_relative', 'namespace_relative', 'mediate_deleted', 'delegate_deleted'] filename = r'(\/|\@\{\S*\})\S*' aa_regex_map = { 'FILENAME': filename, 'FILE': r'\v^\s*(audit\s+)?(deny\s+|allow\s+)?(owner\s+|other\s+)?' + filename + r'\s+', # Start of a file rule # (whitespace_+_, owner etc. flag_?_, filename pattern, whitespace_+_) 'DENYFILE': r'\v^\s*(audit\s+)?deny\s+(owner\s+|other\s+)?' + filename + r'\s+', # deny, otherwise like FILE 'auditdenyowner': r'(audit\s+)?(deny\s+|allow\s+)?(owner\s+|other\s+)?', 'audit_DENY_owner': r'(audit\s+)?deny\s+(owner\s+|other\s+)?', # must include "deny", otherwise like auditdenyowner 'auditdeny': r'(audit\s+)?(deny\s+|allow\s+)?', 'EOL': r'\s*,(\s*$|(\s*#.*$)\@=)', # End of a line (whitespace_?_, comma, whitespace_?_ comment.*) 'TRANSITION': r'(\s+-\>\s+\S+)?', 'sdKapKey': " ".join(benign_caps), 'sdKapKeyDanger': " ".join(danger_caps), 'sdKapKeyRegex': "|".join(capabilities), 'sdNetworkType': aa_network_types, 'sdNetworkProto': "|".join(af_names), 'flags': r'((flags\s*\=\s*)?\(\s*(' + '|'.join(aa_flags) + r')(\s*,\s*(' + '|'.join(aa_flags) + r'))*\s*\)\s+)', } def my_repl(matchobj): matchobj.group(1) if matchobj.group(1) in aa_regex_map: return aa_regex_map[matchobj.group(1)] return matchobj.group(0) def create_file_rule(highlighting, permissions, comment, denyrule=0): if denyrule == 0: keywords = '@@auditdenyowner@@' else: keywords = '@@audit_DENY_owner@@' # TODO: not defined yet, will be '(audit\s+)?deny\s+(owner\s+)?' sniplet = '' sniplet = sniplet + "\n" + '" ' + comment + "\n" prefix = r'syn match ' + highlighting + r' /\v^\s*' + keywords suffix = r'@@EOL@@/ contains=sdGlob,sdComment nextgroup=@sdEntry,sdComment,sdError,sdInclude' + "\n" # filename without quotes sniplet = sniplet + prefix + r'@@FILENAME@@\s+' + permissions + suffix # filename with quotes sniplet = sniplet + prefix + r'"@@FILENAME@@"\s+' + permissions + suffix # filename without quotes, reverse syntax sniplet = sniplet + prefix + permissions + r'\s+@@FILENAME@@' + suffix # filename with quotes, reverse syntax sniplet = sniplet + prefix + permissions + r'\s+"@@FILENAME@@"+' + suffix return sniplet filerule = '' filerule = filerule + create_file_rule('sdEntryWriteExec ', r'(l|r|w|a|m|k|[iuUpPcC]x)+@@TRANSITION@@', 'write + exec/mmap - danger! (known bug: accepts aw to keep things simple)') filerule = filerule + create_file_rule('sdEntryUX', r'(r|m|k|ux|pux)+@@TRANSITION@@', 'ux(mr) - unconstrained entry, flag the line red. also includes pux which is unconstrained if no profile exists') filerule = filerule + create_file_rule('sdEntryUXe', r'(r|m|k|Ux|PUx)+@@TRANSITION@@', 'Ux(mr) and PUx(mr) - like ux + clean environment') filerule = filerule + create_file_rule('sdEntryPX', r'(r|m|k|px|cx|pix|cix)+@@TRANSITION@@', 'px/cx/pix/cix(mrk) - standard exec entry, flag the line blue') filerule = filerule + create_file_rule('sdEntryPXe', r'(r|m|k|Px|Cx|Pix|Cix)+@@TRANSITION@@', 'Px/Cx/Pix/Cix(mrk) - like px/cx + clean environment') filerule = filerule + create_file_rule('sdEntryIX', r'(r|m|k|ix)+', 'ix(mr) - standard exec entry, flag the line green') filerule = filerule + create_file_rule('sdEntryM', r'(r|m|k)+', 'mr - mmap with PROT_EXEC') filerule = filerule + create_file_rule('sdEntryM', r'(r|m|k|x)+', 'special case: deny x is allowed (does not need to be ix, px, ux or cx)', 1) #syn match sdEntryM /@@DENYFILE@@(r|m|k|x)+@@EOL@@/ contains=sdGlob,sdComment nextgroup=@sdEntry,sdComment,sdError,sdInclude filerule = filerule + create_file_rule('sdError', r'\S*(w\S*a|a\S*w)\S*', 'write + append is an error') filerule = filerule + create_file_rule('sdEntryW', r'(l|r|w|k)+', 'write entry, flag the line yellow') filerule = filerule + create_file_rule('sdEntryW', r'(l|r|a|k)+', 'append entry, flag the line yellow') filerule = filerule + create_file_rule('sdEntryK', r'[rlk]+', 'read entry + locking, currently no highlighting') filerule = filerule + create_file_rule('sdEntryR', r'[rl]+', 'read entry, no highlighting') # " special case: deny x is allowed (doesn't need to be ix, px, ux or cx) # syn match sdEntryM /@@DENYFILE@@(r|m|k|x)+@@EOL@@/ contains=sdGlob,sdComment nextgroup=@sdEntry,sdComment,sdError,sdInclude # " TODO: Support filenames enclosed in quotes ("/home/foo/My Documents/") - ideally by only allowing quotes pair-wise regex = "@@(" + "|".join(aa_regex_map) + ")@@" sys.stdout.write('" generated from apparmor.vim.in by create-apparmor.vim.py\n') sys.stdout.write('" do not edit this file - edit apparmor.vim.in or create-apparmor.vim.py instead' + "\n\n") with open("apparmor.vim.in") as template: for line in template: line = re.sub(regex, my_repl, line.rstrip()) sys.stdout.write('%s\n' % line) sys.stdout.write("\n\n\n\n") sys.stdout.write('" file rules added with create_file_rule()\n') sys.stdout.write(re.sub(regex, my_repl, filerule) + '\n') apparmor-2.13.3/utils/aa-mergeprof.80000644000175000017500000001142113502024375015007 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "AA-MERGEPROF 8" .TH AA-MERGEPROF 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa\-mergeprof \- merge AppArmor security profiles. .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-mergeprof \f(BIfile\fB [\f(BIfile\fB ...] [\f(BI\-d /path/to/profiles\fB]\fR .SH "OPTIONS" .IX Header "OPTIONS" \&\fBfile\fR .PP .Vb 1 \& One or more files containing profiles to merge into the profile directory (see \-d). .Ve .PP \&\fB\-d \-\-dir /path/to/profiles\fR .PP .Vb 2 \& Specifies the target directory for the merged AppArmor security profile set. \& Defaults to /etc/apparmor.d. .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBaa-mergeprof\fR .SH "BUGS" .IX Header "BUGS" If you find any bugs, please report them at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7), \fIapparmor.d\fR\|(5), \fIaa_change_hat\fR\|(2), \fIaa\-genprof\fR\|(1), \&\fIaa\-logprof\fR\|(1), \fIaa\-enforce\fR\|(1), \fIaa\-audit\fR\|(1), \fIaa\-complain\fR\|(1), \&\fIaa\-disable\fR\|(1), and . apparmor-2.13.3/utils/aa-easyprof.8.html0000644000175000017500000003134413502024375015622 0ustar jjjj
 

NAME

aa-easyprof - AppArmor profile generation made easy.

SYNOPSIS

aa-easyprof [option] <path to binary>

DESCRIPTION

aa-easyprof provides an easy to use interface for AppArmor policy generation. aa-easyprof supports the use of templates and policy groups to quickly profile an application. Please note that while this tool can help with policy generation, its utility is dependent on the quality of the templates, policy groups and abstractions used. Also, this tool may create policy which is less restricted than creating policy by hand or with aa-genprof and aa-logprof.

OPTIONS

aa-easyprof accepts the following arguments:

-t TEMPLATE, --template=TEMPLATE

Specify which template to use. May specify either a system template from /usr/share/apparmor/easyprof/templates or a filename for the template to use. If not specified, use /usr/share/apparmor/easyprof/templates/default.

-p POLICYGROUPS, --policy-groups=POLICYGROUPS

Specify POLICY as a comma-separated list of policy groups. See --list-templates for supported policy groups. The available policy groups are in /usr/share/apparmor/easyprof/policy. Policy groups are simply groupings of AppArmor rules or policies. They are similar to AppArmor abstractions, but usually encompass more policy rules.

--parser PATH

Specify the PATH of the apparmor_parser binary to use when verifying policy. If this option is not specified, aa-easyprof will attempt to locate the path starting with /sbin/apparmor_parser.

-a ABSTRACTIONS, --abstractions=ABSTRACTIONS

Specify ABSTRACTIONS as a comma-separated list of AppArmor abstractions. It is usually recommended you use policy groups instead, but this is provided as a convenience. AppArmor abstractions are located in /etc/apparmor.d/abstractions. See apparmor.d(5) for details.

-b PATH, --base=PATH

Set the base PATH for resolving abstractions specified by --abstractions. See the same option in apparmor_parser(8) for details.

-I PATH, --Include=PATH

Add PATH to the search paths used for resolving abstractions specified by --abstractions. See the same option in apparmor_parser(8) for details.

-r PATH, --read-path=PATH

Specify a PATH to allow owner reads. May be specified multiple times. If the PATH ends in a '/', then PATH is treated as a directory and reads are allowed to all files under this directory. Can optionally use '/*' at the end of the PATH to only allow reads to files directly in PATH.

-w PATH, --write-dir=PATH

Like --read-path but also allow owner writes in additions to reads.

-n NAME, --name=NAME

Specify NAME of policy. If not specified, NAME is set to the name of the binary. The NAME of the policy is typically only used for profile meta data and does not specify the AppArmor profile name.

--profile-name=PROFILENAME

Specify the AppArmor profile name. When set, uses 'profile PROFILENAME' in the profile. When set and specifying a binary, uses 'profile PROFILENAME BINARY' in the profile. If not set, the binary will be used as the profile name and profile attachment.

--template-var="@{VAR}=VALUE"

Set VAR to VALUE in the resulting policy. This typically only makes sense if the specified template uses this value. May be specified multiple times.

--list-templates

List available templates.

--show-template

Display template specified with --template.

--templates-dir=PATH

Use PATH instead of system templates directory.

--include-templates-dir=PATH

Include PATH when searching for templates in addition to the system templates directory (or the one specified with --templates-dir). System templates will match before those in PATH.

--list-policy-groups

List available policy groups.

--show-policy-group

Display policy groups specified with --policy-groups.

--policy-groups-dir=PATH

Use PATH instead of system policy-groups directory.

--include-policy-groups-dir=PATH

Include PATH when searching for policy groups in addition to the system policy-groups directory (or the one specified with --policy-groups-dir). System policy-groups will match before those in PATH.

--policy-version=VERSION

Must be used with --policy-vendor and is used to specify the version of policy groups and templates. When specified, aa-easyprof looks for the subdirectory VENDOR/VERSION within the policy-groups and templates directory. The specified version must be a positive decimal number compatible with the JSON Number type. Eg, when using:

    $ aa-easyprof --templates-dir=/usr/share/apparmor/easyprof/templates \
                  --policy-groups-dir=/usr/share/apparmor/easyprof/policygroups \
                  --policy-vendor="foo" \
                  --policy-version=1.0

Then /usr/share/apparmor/easyprof/templates/foo/1.0 will be searched for templates and /usr/share/apparmor/easyprof/policygroups/foo/1.0 for policy groups.

--policy-vendor=VENDOR

Must be used with --policy-version and is used to specify the vendor for policy groups and templates. See --policy-version for more information.

--author

Specify author of the policy.

Specify copyright of the policy.

--comment

Specify comment for the policy.

-m MANIFEST, --manifest=MANIFEST

aa-easyprof also supports using a JSON manifest file for specifying options related to policy. Unlike command line arguments, the JSON file may specify multiple profiles. The structure of the JSON is:

  {
    "security": {
      "profiles": {
        "<profile name 1>": {
          ... attributes specific to this profile ...
        },
        "<profile name 2>": {
          ...
        }
      }
    }
  }

Each profile JSON object (ie, everything under a profile name) may specify any fields related to policy. The "security" JSON container object is optional and may be omitted. An example manifest file demonstrating all fields is:

  {
    "security": {
      "profiles": {
        "com.example.foo": {
          "abstractions": [
            "audio",
            "gnome"
          ],
          "author": "Your Name",
          "binary": "/opt/foo/**",
          "comment": "Unstructured single-line comment",
          "copyright": "Unstructured single-line copyright statement",
          "name": "My Foo App",
          "policy_groups": [
            "networking",
            "user-application"
          ],
          "policy_vendor": "somevendor",
          "policy_version": 1.0,
          "read_path": [
            "/tmp/foo_r",
            "/tmp/bar_r/"
          ],
          "template": "user-application",
          "template_variables": {
            "APPNAME": "foo",
            "VAR1": "bar",
            "VAR2": "baz"
          },
          "write_path": [
            "/tmp/foo_w",
            "/tmp/bar_w/"
          ]
        }
      }
    }
  }

A manifest file does not have to include all the fields. Eg, a manifest file for an Ubuntu SDK application might be:

  {
    "security": {
      "profiles": {
        "com.ubuntu.developer.myusername.MyCoolApp": {
          "policy_groups": [
            "networking",
            "online-accounts"
          ],
          "policy_vendor": "ubuntu",
          "policy_version": 1.0,
          "template": "ubuntu-sdk",
          "template_variables": {
            "APPNAME": "MyCoolApp",
            "APPVERSION": "0.1.2"
          }
        }
      }
    }
  }
--verify-manifest

When used with --manifest, warn about potentially unsafe definitions in the manifest file.

--output-format=FORMAT

Specify either text (default if unspecified) for AppArmor policy output or json for JSON manifest format.

--output-directory=DIR

Specify output directory for profile. If unspecified, policy is sent to stdout.

EXAMPLES

Example usage for a program named 'foo' which is installed in /opt/foo:

    $ aa-easyprof --template=user-application --template-var="@{APPNAME}=foo" \
                  --policy-groups=opt-application,user-application \
                  /opt/foo/bin/FooApp

When using a manifest file:

    $ aa-easyprof --manifest=manifest.json

To output a manifest file based on aa-easyprof arguments:

    $ aa-easyprof --output-format=json \
                  --author="Your Name" \
                  --comment="Unstructured single-line comment" \
                  --copyright="Unstructured single-line copyright statement" \
                  --name="My Foo App" \
                  --profile-name="com.example.foo" \
                  --template="user-application" \
                  --policy-groups="user-application,networking" \
                  --abstractions="audio,gnome" \
                  --read-path="/tmp/foo_r" \
                  --read-path="/tmp/bar_r/" \
                  --write-path="/tmp/foo_w" \
                  --write-path=/tmp/bar_w/ \
                  --template-var="@{APPNAME}=foo" \
                  --template-var="@{VAR1}=bar" \
                  --template-var="@{VAR2}=baz" \
                  "/opt/foo/**"

BUGS

If you find any additional bugs, please report them to Launchpad at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7) apparmor.d(5)

 
apparmor-2.13.3/utils/aa-autodep.pod0000644000175000017500000000456413502024172015102 0ustar jjjj# This publication is intellectual property of Novell Inc. and Canonical # Ltd. Its contents can be duplicated, either in part or in whole, provided # that a copyright label is visibly located on each copy. # # All information found in this book has been compiled with utmost # attention to detail. However, this does not guarantee complete accuracy. # Neither SUSE LINUX GmbH, Canonical Ltd, the authors, nor the translators # shall be held liable for possible errors or the consequences thereof. # # Many of the software and hardware descriptions cited in this book # are registered trademarks. All trade names are subject to copyright # restrictions and may be registered trade marks. SUSE LINUX GmbH # and Canonical Ltd. essentially adhere to the manufacturer's spelling. # # Names of products and trademarks appearing in this book (with or without # specific notation) are likewise subject to trademark and trade protection # laws and may thus fall under copyright restrictions. # =pod =head1 NAME aa-autodep - guess basic AppArmor profile requirements =head1 SYNOPSIS BexecutableE> [IexecutableE> ...] [I<-d /path/to/profiles>] [I<-f>]> =head1 OPTIONS B<-d --dir /path/to/profiles> Specifies where to look for the AppArmor security profile set. Defaults to /etc/apparmor.d. B<-f --force> Overwrites any existing AppArmor profile for the executable with the generated minimal AppArmor profile. =head1 DESCRIPTION B is used to generate a minimal AppArmor profile for a set of executables. This program will generate a profile for binary executable as well as interpreted script programs. At a minimum aa-autodep will provide a base profile containing a base include directive which includes basic profile entries needed by most programs. The profile is generated by recursively calling ldd(1) on the executables listed on the command line. The I<--force> option will overwrite any existing profile for the executable with the newly generated minimal AppArmor profile. =head1 BUGS This program does not perform full static analysis of executables, so the profiles generated are necessarily incomplete. If you find any bugs, please report them at L. =head1 SEE ALSO apparmor(7), apparmor.d(5), aa-complain(1), aa-enforce(1), aa-disable(1), aa_change_hat(2), and L. =cut apparmor-2.13.3/utils/aa-logprof0000755000175000017500000000376013502024172014330 0ustar jjjj#! /usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import argparse import os import apparmor.aa as apparmor import apparmor.ui as aaui # setup exception handling from apparmor.fail import enable_aa_exception_handler enable_aa_exception_handler() # setup module translations from apparmor.translations import init_translation _ = init_translation() parser = argparse.ArgumentParser(description=_('Process log entries to generate profiles')) parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) parser.add_argument('-f', '--file', type=str, help=_('path to logfile')) parser.add_argument('-m', '--mark', type=str, help=_('mark in the log to start processing after')) parser.add_argument('-j', '--json', action='store_true', help=_('Input and Output in JSON')) args = parser.parse_args() if args.json: aaui.set_json_mode() profiledir = args.dir logmark = args.mark or '' apparmor.init_aa() apparmor.set_logfile(args.file) aa_mountpoint = apparmor.check_for_apparmor() if not aa_mountpoint: raise apparmor.AppArmorException(_('It seems AppArmor was not started. Please enable AppArmor and try again.')) if profiledir: apparmor.profile_dir = apparmor.get_full_path(profiledir) if not os.path.isdir(apparmor.profile_dir): raise apparmor.AppArmorException("%s is not a directory."%profiledir) apparmor.loadincludes() apparmor.do_logprof_pass(logmark) apparmor-2.13.3/utils/easyprof/0000755000175000017500000000000013502024172014175 5ustar jjjjapparmor-2.13.3/utils/easyprof/easyprof.conf0000644000175000017500000000026613502024172016700 0ustar jjjj# Location of system policygroups POLICYGROUPS_DIR="/usr/share/apparmor/easyprof/policygroups" # Location of system templates TEMPLATES_DIR="/usr/share/apparmor/easyprof/templates" apparmor-2.13.3/utils/easyprof/templates/0000755000175000017500000000000013502024172016173 5ustar jjjjapparmor-2.13.3/utils/easyprof/templates/user-application0000644000175000017500000000106213502024172021374 0ustar jjjj# # Example usage for a program named 'foo' which is installed in /opt/foo # $ aa-easyprof --template=user-application \ # --template-var="@{APPNAME}=foo" \ # --policy-groups=opt-application,user-application \ # /opt/foo/bin/foo # ###ENDUSAGE### # vim:syntax=apparmor # AppArmor policy for ###NAME### # ###AUTHOR### # ###COPYRIGHT### # ###COMMENT### #include ###VAR### ###PROFILEATTACH### { #include ###ABSTRACTIONS### ###POLICYGROUPS### ###READS### ###WRITES### } apparmor-2.13.3/utils/easyprof/templates/default0000644000175000017500000000056413502024172017547 0ustar jjjj# # Example usage: # $ aa-easyprof --policy-groups=user-application /usr/bin/foo # ###ENDUSAGE### # vim:syntax=apparmor # AppArmor policy for ###NAME### # ###AUTHOR### # ###COPYRIGHT### # ###COMMENT### #include ###VAR### ###PROFILEATTACH### { #include ###ABSTRACTIONS### ###POLICYGROUPS### ###READS### ###WRITES### } apparmor-2.13.3/utils/easyprof/templates/sandbox0000644000175000017500000000102613502024172017553 0ustar jjjj# # Example usage for a program named 'foo' which is installed in /opt/foo # $ aa-easyprof --template=sandbox \ # --template-var="@{APPNAME}=foo" \ # --policy-groups=opt-application,user-application \ # /opt/foo/bin/foo # ###ENDUSAGE### # vim:syntax=apparmor # AppArmor policy for ###NAME### #include ###VAR### ###PROFILEATTACH### { #include / r, /**/ r, /usr/** r, ###ABSTRACTIONS### ###POLICYGROUPS### ###READS### ###WRITES### } apparmor-2.13.3/utils/easyprof/templates/sandbox-x0000644000175000017500000000166613502024172020032 0ustar jjjj# # Example usage for a program named 'foo' which is installed in /opt/foo # $ aa-easyprof --template=sandbox \ # --template-var="@{APPNAME}=foo" \ # --policy-groups=opt-application,user-application \ # /opt/foo/bin/foo # ###ENDUSAGE### # vim:syntax=apparmor # AppArmor policy for ###NAME### #include ###VAR### ###PROFILEATTACH### { #include #include #include #include audit deny @{HOME}/.Xauthority mrwlk, /etc/passwd r, / r, /**/ r, /usr/** r, /var/lib/dbus/machine-id r, owner @{PROC}/[0-9]*/auxv r, owner @{PROC}/[0-9]*/fd/ r, owner @{PROC}/[0-9]*/environ r, owner @{PROC}/[0-9]*/mounts r, owner @{PROC}/[0-9]*/smaps r, owner @{PROC}/[0-9]*/statm r, owner @{PROC}/[0-9]*/task/[0-9]*/stat r, ###ABSTRACTIONS### ###POLICYGROUPS### ###READS### ###WRITES### } apparmor-2.13.3/utils/easyprof/README0000644000175000017500000000303413502024172015055 0ustar jjjjAppArmor Easy Profiler ---------------------- aa-easyprof is a standalone CLI application which can also be imported into developer SDKs. See test/test-aa-easyprof.py for an example of how to import this into your SDK. Templates --------- Any number of templates can be used. The user may specify one on the command line or use a system-wide template from /usr/share/apparmor/easyprof/templates. Currently the combination of the user-application and the opt-application and user-application policygroups should achieve a working policy for Ubuntu's Application Review Board: - http://developer.ubuntu.com/publish/my-apps-packages/ Eg: $ aa-easyprof --template=user-application \ --template-var="@{APPNAME}=foo" \ --policy-groups=opt-application,user-application \ /opt/foo/bin/foo Testing ------- Unit tests: $ ./test/test-aa-easyprof.py In source manual testing: $ ./aa-easyprof --templates-dir=./easyprof/templates \ --policy-groups-dir=./easyprof/policygroups \ ... \ /opt/foo/bin/foo Post-install manual testing: $ make DESTDIR=/tmp/test PERLDIR=/tmp/test/usr/share/perl5/Immunix install $ cd /tmp/test $ PYTHONPATH=/tmp/test/usr/local/.../dist-packages ./usr/bin/aa-easyprof \ --templates-dir=/tmp/test/usr/share/apparmor/easyprof/templates \ --policy-groups-dir=/tmp/test/usr/share/apparmor/easyprof/policygroups \ /opt/bin/foo (you may also adjust /tmp/test/etc/apparmor/easyprof.conf to avoid specifying --templates-dir and --policy-groups-dir). apparmor-2.13.3/utils/easyprof/policygroups/0000755000175000017500000000000013502024172016734 5ustar jjjjapparmor-2.13.3/utils/easyprof/policygroups/user-application0000644000175000017500000000060213502024172022134 0ustar jjjj# Policy group allowing various writes to standard directories in @{HOMEDIRS} #include owner @{HOMEDIRS}/.cache/@{APPNAME}/ rw, owner @{HOMEDIRS}/.cache/@{APPNAME}/** rwkl, owner @{HOMEDIRS}/.config/@{APPNAME}/ rw, owner @{HOMEDIRS}/.config/@{APPNAME}/** rwkl, owner @{HOMEDIRS}/.local/share/@{APPNAME}/ rw, owner @{HOMEDIRS}/.local/share/@{APPNAME}/** rwkl, apparmor-2.13.3/utils/easyprof/policygroups/opt-application0000644000175000017500000000013613502024172021762 0ustar jjjj# Policy group for applications installed in /opt /opt/@{APPNAME}/ r, /opt/@{APPNAME}/** mrk, apparmor-2.13.3/utils/aa-status.8.html0000644000175000017500000001035313502024376015313 0ustar jjjj
 

NAME

aa-status - display various information about the current AppArmor policy.

SYNOPSIS

aa-status [option]

DESCRIPTION

aa-status will report various aspects of the current state of AppArmor confinement. By default, it displays the same information as if the --verbose argument were given. A sample of what this looks like is:

  apparmor module is loaded.
  110 profiles are loaded.
  102 profiles are in enforce mode.
  8 profiles are in complain mode.
  Out of 129 processes running:
  13 processes have profiles defined.
  8 processes have profiles in enforce mode.
  5 processes have profiles in complain mode.

Other argument options are provided to report individual aspects, to support being used in scripts.

OPTIONS

aa-status accepts only one argument at a time out of:

--enabled

returns error code if AppArmor is not enabled.

--profiled

displays the number of loaded AppArmor policies.

--enforced

displays the number of loaded enforcing AppArmor policies.

--complaining

displays the number of loaded non-enforcing AppArmor policies.

--verbose

displays multiple data points about loaded AppArmor policy set (the default action if no arguments are given).

--json

displays multiple data points about loaded AppArmor policy set in a JSON format, fit for machine consumption.

--pretty-json

same as --json, formatted to be readable by humans as well as by machines.

--help

displays a short usage statement.

EXIT STATUS

Upon exiting, aa-status will set its exit status to the following values:

0

if apparmor is enabled and policy is loaded.

1

if apparmor is not enabled/loaded.

2

if apparmor is enabled but no policy is loaded.

3

if the apparmor control files aren't available under /sys/kernel/security/.

4

if the user running the script doesn't have enough privileges to read the apparmor control files.

BUGS

aa-status must be run as root to read the state of the loaded policy from the apparmor module. It uses the /proc filesystem to determine which processes are confined and so is susceptible to race conditions.

If you find any additional bugs, please report them at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7), apparmor.d(5), and https://wiki.apparmor.net.

 
apparmor-2.13.3/utils/aa-genprof0000755000175000017500000001532613502024172014321 0ustar jjjj#! /usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import argparse import atexit import os import re import subprocess import sys import apparmor.aa as apparmor import apparmor.ui as aaui from apparmor.common import warn # setup exception handling from apparmor.fail import enable_aa_exception_handler enable_aa_exception_handler() # setup module translations from apparmor.translations import init_translation _ = init_translation() def sysctl_read(path): value = None with open(path, 'r') as f_in: value = int(f_in.readline()) return value def sysctl_write(path, value): if value is None: warn('Not writing invalid value "None" to %s'%path) return with open(path, 'w') as f_out: f_out.write(str(value)) def last_audit_entry_time(): out = subprocess.check_output(['tail', '-1', apparmor.logfile]) logmark = None out = out.decode('ascii') if re.search('^.*msg\=audit\((\d+\.\d+\:\d+).*\).*$', out): logmark = re.search('^.*msg\=audit\((\d+\.\d+\:\d+).*\).*$', out).groups()[0] else: logmark = '' return logmark def restore_ratelimit(): try: sysctl_write(ratelimit_sysctl, ratelimit_saved) except PermissionError: if ratelimit_saved != sysctl_read(ratelimit_sysctl): raise # happens only if a) running under lxd and b) something changed the ratelimit since starting aa-genprof parser = argparse.ArgumentParser(description=_('Generate profile for the given program')) parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) parser.add_argument('-f', '--file', type=str, help=_('path to logfile')) parser.add_argument('program', type=str, help=_('name of program to profile')) parser.add_argument('-j', '--json', action="store_true", help=_('Input and Output in JSON')) args = parser.parse_args() if args.json: aaui.set_json_mode() profiling = args.program profiledir = args.dir apparmor.init_aa() apparmor.set_logfile(args.file) aa_mountpoint = apparmor.check_for_apparmor() if not aa_mountpoint: raise apparmor.AppArmorException(_('It seems AppArmor was not started. Please enable AppArmor and try again.')) if profiledir: apparmor.profile_dir = apparmor.get_full_path(profiledir) if not os.path.isdir(apparmor.profile_dir): raise apparmor.AppArmorException(_("%s is not a directory.") %profiledir) program = None #if os.path.exists(apparmor.which(profiling.strip())): if os.path.exists(profiling): program = apparmor.get_full_path(profiling) else: if '/' not in profiling: which = apparmor.which(profiling) if which: program = apparmor.get_full_path(which) if not program or not os.path.exists(program): if '/' not in profiling: raise apparmor.AppArmorException(_("Can't find %(profiling)s in the system path list. If the name of the application\nis correct, please run 'which %(profiling)s' as a user with correct PATH\nenvironment set up in order to find the fully-qualified path and\nuse the full path as parameter.") % { 'profiling': profiling }) else: raise apparmor.AppArmorException(_('%s does not exists, please double-check the path.') %profiling) # Check if the program has been marked as not allowed to have a profile apparmor.check_qualifiers(program) apparmor.loadincludes() profile_filename = apparmor.get_profile_filename_from_attachment(program, True) if os.path.exists(profile_filename): apparmor.helpers[program] = apparmor.get_profile_flags(profile_filename, program) else: apparmor.autodep(program) apparmor.helpers[program] = 'enforce' if apparmor.helpers[program] == 'enforce': apparmor.complain(program) apparmor.reload(program) # When reading from syslog, it is possible to hit the default kernel # printk ratelimit. This will result in audit entries getting skipped, # making profile generation inaccurate. When using genprof, disable # the printk ratelimit, and restore it on exit. ratelimit_sysctl = '/proc/sys/kernel/printk_ratelimit' ratelimit_saved = sysctl_read(ratelimit_sysctl) try: sysctl_write(ratelimit_sysctl, 0) except PermissionError: # will fail in lxd warn("Can't set printk_ratelimit, some events might be lost") atexit.register(restore_ratelimit) aaui.UI_Info(_('\nBefore you begin, you may wish to check if a\nprofile already exists for the application you\nwish to confine. See the following wiki page for\nmore information:')+'\nhttps://gitlab.com/apparmor/apparmor/wikis/Profiles') syslog = True logmark = '' done_profiling = False if os.path.exists('/var/log/audit/audit.log'): syslog = False passno = 0 while not done_profiling: if syslog: logmark = subprocess.check_output(['date | md5sum'], shell=True) logmark = logmark.decode('ascii').strip() logmark = re.search('^([0-9a-f]+)', logmark).groups()[0] t=subprocess.call("%s -p kern.warn 'GenProf: %s'"%(apparmor.logger_path(), logmark), shell=True) else: logmark = last_audit_entry_time() q = aaui.PromptQuestion() q.headers = [_('Profiling'), program] q.functions = ['CMD_SCAN', 'CMD_FINISHED'] q.default = 'CMD_SCAN' q.explanation = _('Please start the application to be profiled in\nanother window and exercise its functionality now.\n\nOnce completed, select the "Scan" option below in \norder to scan the system logs for AppArmor events. \n\nFor each AppArmor event, you will be given the \nopportunity to choose whether the access should be \nallowed or denied.') ans, arg = q.promptUser('noexit') if ans == 'CMD_SCAN': lp_ret = apparmor.do_logprof_pass(logmark, passno) passno += 1 if lp_ret == 'FINISHED': done_profiling = True else: done_profiling = True for p in sorted(apparmor.helpers.keys()): if apparmor.helpers[p] == 'enforce': apparmor.enforce(p) apparmor.reload(p) aaui.UI_Info(_('\nReloaded AppArmor profiles in enforce mode.')) aaui.UI_Info(_('\nPlease consider contributing your new profile!\nSee the following wiki page for more information:')+'\nhttps://gitlab.com/apparmor/apparmor/wikis/Profiles\n') aaui.UI_Info(_('Finished generating profile for %s.')%program) sys.exit(0) apparmor-2.13.3/utils/aa-audit.80000644000175000017500000001201413502024375014126 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "AA-AUDIT 8" .TH AA-AUDIT 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa\-audit \- set an AppArmor security profile to audit mode. .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-audit \f(BI\fB [\f(BI\fB ...] [\f(BI\-d /path/to/profiles\fB] [\f(BI\-\-no\-reload\fB] [\f(BI\-r\fB]\fR .SH "OPTIONS" .IX Header "OPTIONS" \&\fB\-d \-\-dir /path/to/profiles\fR .PP .Vb 2 \& Specifies where to look for the AppArmor security profile set. \& Defaults to /etc/apparmor.d. .Ve .PP \&\fB\-\-no\-reload\fR Do not reload the profile after modifying it. .PP \&\fB\-r \-\-remove\fR .PP .Vb 1 \& Removes the audit mode for the profile. .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBaa-audit\fR is used to set one or more profiles to audit mode. In this mode security policy is enforced and all access (successes and failures) are logged to the system log. .PP The \fI\-\-remove\fR option can be used to remove the audit mode for the profile. .SH "BUGS" .IX Header "BUGS" If you find any bugs, please report them at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7), \fIapparmor.d\fR\|(5), \fIaa\-enforce\fR\|(1), \fIaa\-complain\fR\|(1), \fIaa\-disable\fR\|(1), \&\fIaa_change_hat\fR\|(2), and . apparmor-2.13.3/utils/aa-complain.80000644000175000017500000001165113502024375014630 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "AA-COMPLAIN 8" .TH AA-COMPLAIN 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa\-complain \- set an AppArmor security profile to complain mode. .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-complain \f(BI\fB [\f(BI\fB ...] [\f(BI\-d /path/to/profiles\fB] [\f(BI\-\-no\-reload\fB]\fR .SH "OPTIONS" .IX Header "OPTIONS" \&\fB\-d \-\-dir /path/to/profiles\fR .PP .Vb 2 \& Specifies where to look for the AppArmor security profile set. \& Defaults to /etc/apparmor.d. .Ve .PP \&\fB\-\-no\-reload\fR Do not reload the profile after modifying it. .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBaa-complain\fR is used to set the enforcement mode for one or more profiles to \fIcomplain\fR mode. In this mode security policy is not enforced but rather access violations are logged to the system log. .PP Note that 'deny' rules will be enforced even in complain mode. .SH "BUGS" .IX Header "BUGS" If you find any bugs, please report them at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7), \fIapparmor.d\fR\|(5), \fIaa\-enforce\fR\|(1), \fIaa\-disable\fR\|(1), \&\fIaa_change_hat\fR\|(2), and . apparmor-2.13.3/utils/aa-decode0000755000175000017500000000531413502024172014100 0ustar jjjj#!/bin/bash # # Copyright (C) 2009-2010, 2012 Canonical Ltd. # Copyright (C) 2012 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Canonical, Ltd. # set -e help() { cat < Decode a hex-encoded string to ASCII. It will also take an audit log on standard input and convert any hex-encoded AppArmor log entries and display them on standard output. OPTIONS: --help display this help EXAMPLES: $ aa-decode 2F746D702F666F6F20626172 Decoded: /tmp/foo bar $ cat /var/log/kern.log | aa-decode ... denied_mask="r::" fsuid=1000 ouid=1000 name=/tmp/foo bar EOM } decode() { decoded=`perl -le "\\$s = uc('$1') ; if (\\$s =~ /^[0-9A-F]*$/) { print pack 'H*', \\$s; }"` echo "$decoded" } if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then help exit fi # if have an argument, then use it, otherwise process stdin if [ -n "$1" ]; then e="$1" if ! echo "$e" | egrep -q "^[0-9A-Fa-f]+$" ; then echo "String should only contain hex characters (0-9, a-f, A-F)" exit 1 fi d=`decode $e` if [ -z "$d" ]; then echo "Could not decode string" exit 1 fi echo "Decoded: $d" exit 0 fi # For now just look at 'name=...' and 'profile=...', # so validate input against this and output based on it. # TODO: better handle other cases too while read line ; do # check if line contains encoded name= or profile= if [[ "$line" =~ \ (name|profile|proctitle)=[0-9a-fA-F] ]]; then # cut the encoded filename/profile name out of the line and decode it ne=`echo "$line" | sed 's/.* name=\([^ ]*\).*$/\\1/g'` nd="$(decode ${ne/\'/\\\'})" pe=`echo "$line" | sed 's/.* profile=\([^ ]*\).*$/\\1/g'` pd="$(decode ${pe/\'/\\\'})" pce=`echo "$line" | sed 's/.* proctitle=\([^ ]*\).*$/\\1/g'` pcd="$(decode ${pce/\'/\\\'})" # replace encoded name and profile with its decoded counterparts (only if it was encoded) test -n "$nd" && line="${line/name=$ne/name=\"$nd\"}" test -n "$pd" && line="${line/profile=$pe/profile=\"$pd\"}" test -n "$pcd" && line="${line/proctitle=$pce/proctitle=\"$pcd\"}" fi echo "$line" done apparmor-2.13.3/utils/aa-audit0000755000175000017500000000274313502024172013766 0ustar jjjj#! /usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import argparse import apparmor.tools # setup exception handling from apparmor.fail import enable_aa_exception_handler enable_aa_exception_handler() # setup module translations from apparmor.translations import init_translation _ = init_translation() parser = argparse.ArgumentParser(description=_('Switch the given programs to audit mode')) parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) parser.add_argument('-r', '--remove', action='store_true', help=_('remove audit mode')) parser.add_argument('program', type=str, nargs='+', help=_('name of program')) parser.add_argument('--no-reload', dest='do_reload', action='store_false', default=True, help=_('Do not reload the profile after modifying it')) args = parser.parse_args() tool = apparmor.tools.aa_tools('audit', args) tool.cmd_audit() apparmor-2.13.3/utils/aa-cleanprof0000755000175000017500000000300613502024172014622 0ustar jjjj#! /usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import argparse import apparmor.tools # setup exception handling from apparmor.fail import enable_aa_exception_handler enable_aa_exception_handler() # setup module translations from apparmor.translations import init_translation _ = init_translation() parser = argparse.ArgumentParser(description=_('Cleanup the profiles for the given programs')) parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) parser.add_argument('program', type=str, nargs='+', help=_('name of program')) parser.add_argument('-s', '--silent', action='store_true', help=_('Silently overwrite with a clean profile')) parser.add_argument('--no-reload', dest='do_reload', action='store_false', default=True, help=_('Do not reload the profile after modifying it')) args = parser.parse_args() clean = apparmor.tools.aa_tools('cleanprof', args) clean.cleanprof_act() apparmor-2.13.3/utils/aa-autodep.8.html0000644000175000017500000000540713502024375015434 0ustar jjjj
 

NAME

aa-autodep - guess basic AppArmor profile requirements

SYNOPSIS

aa-autodep <executable> [<executable> ...] [-d /path/to/profiles] [-f]

OPTIONS

-d --dir /path/to/profiles

   Specifies where to look for the AppArmor security profile set.
   Defaults to /etc/apparmor.d.

-f --force

   Overwrites any existing AppArmor profile for the executable with the generated minimal AppArmor profile.

DESCRIPTION

aa-autodep is used to generate a minimal AppArmor profile for a set of executables. This program will generate a profile for binary executable as well as interpreted script programs. At a minimum aa-autodep will provide a base profile containing a base include directive which includes basic profile entries needed by most programs. The profile is generated by recursively calling ldd(1) on the executables listed on the command line.

The --force option will overwrite any existing profile for the executable with the newly generated minimal AppArmor profile.

BUGS

This program does not perform full static analysis of executables, so the profiles generated are necessarily incomplete. If you find any bugs, please report them at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7), apparmor.d(5), aa-complain(1), aa-enforce(1), aa-disable(1), aa_change_hat(2), and https://wiki.apparmor.net.

 
apparmor-2.13.3/utils/aa-genprof.8.html0000644000175000017500000000706413502024375015434 0ustar jjjj
 

NAME

aa-genprof - profile generation utility for AppArmor

SYNOPSIS

aa-genprof <executable> [-d /path/to/profiles] [-f /path/to/logfile]

OPTIONS

-d --dir /path/to/profiles

   Specifies where to look for the AppArmor security profile set.
   Defaults to /etc/apparmor.d.

-f --file /path/to/logfile

        Specifies the location of logfile.
        Default locations are read from F</etc/apparmor/logprof.conf>.
        Typical defaults are:
                 /var/log/audit/audit.log
                 /var/log/syslog
                 /var/log/messages

DESCRIPTION

When running aa-genprof, you must specify a program to profile. If the specified program is not a fully-qualified path, aa-genprof will search $PATH in order to find the program.

If a profile does not exist for the program, aa-genprof will create one using aa-autodep(1).

Genprof will then:

   - set the profile to complain mode 

   - write a mark to the system log

   - instruct the user to start the application to
     be profiled in another window and exercise its functionality

It then presents the user with two options, (S)can system log for entries to add to profile and (F)inish.

If the user selects (S)can or hits return, aa-genprof will parse the complain mode logs and iterate through generated violations using aa-logprof(1).

After the user finishes selecting profile entries based on violations that were detected during the program execution, aa-genprof will reload the updated profiles in complain mode and again prompt the user for (S)can and (F)inish. This cycle can then be repeated as necessary until all application functionality has been exercised without generating access violations.

When the user eventually hits (F)inish, aa-genprof will set the main profile, and any other profiles that were generated, into enforce mode and exit.

BUGS

If you find any bugs, please report them at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7), apparmor.d(5), aa-enforce(1), aa-complain(1), aa-disable(1), aa_change_hat(2), aa-logprof(1), logprof.conf(5), and https://wiki.apparmor.net.

 
apparmor-2.13.3/utils/aa-cleanprof.8.html0000644000175000017500000000461213502024375015741 0ustar jjjj
 

NAME

aa-cleanprof - clean an existing AppArmor security profile.

SYNOPSIS

aa-cleanprof <executable> [<executable> ...] [-d /path/to/profiles] [--no-reload] [-s]

OPTIONS

-d --dir /path/to/profiles

   Specifies where to look for the AppArmor security profile set.
   Defaults to /etc/apparmor.d.

--no-reload Do not reload the profile after modifying it.

-s --silent

   Silently overwrites the profile without user prompt.

DESCRIPTION

aa-cleanprof is used to perform a cleanup on one or more profiles. The tool removes any existing superfluous rules (rules that are covered under an include or another rule), reorders the rules to group similar rules together and removes all comments from the file.

BUGS

If you find any bugs, please report them at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7), apparmor.d(5), aa-enforce(1), aa-complain(1), aa-disable(1), aa_change_hat(2), and https://wiki.apparmor.net.

 
apparmor-2.13.3/utils/logprof.conf.pod0000644000175000017500000001002713502024172015445 0ustar jjjj# This publication is intellectual property of Novell Inc. and Canonical # Ltd. Its contents can be duplicated, either in part or in whole, provided # that a copyright label is visibly located on each copy. # # All information found in this book has been compiled with utmost # attention to detail. However, this does not guarantee complete accuracy. # Neither SUSE LINUX GmbH, Canonical Ltd, the authors, nor the translators # shall be held liable for possible errors or the consequences thereof. # # Many of the software and hardware descriptions cited in this book # are registered trademarks. All trade names are subject to copyright # restrictions and may be registered trade marks. SUSE LINUX GmbH # and Canonical Ltd. essentially adhere to the manufacturer's spelling. # # Names of products and trademarks appearing in this book (with or without # specific notation) are likewise subject to trademark and trade protection # laws and may thus fall under copyright restrictions. # =pod =head1 NAME logprof.conf - configuration file for expert options that modify the behavior of the AppArmor aa-logprof(1) program. =head1 DESCRIPTION The aa-logprof(1) program can be configured to have certain default behavior by the contents of logprof.conf. The B<[qualifiers]> section lists specific programs that should have a subset of the full ix/px/ux list when asking what mode to execute it using. Since creating a separate profile for /bin/bash is dangerous, we can specify that for /bin/bash, only (I)nherit, (U)nconstrained, and (D)eny should be allowed options and only those will show up in the prompt when we're asking about adding that to a profile. Likewise, if someone currently exec's /bin/mount in ix or px mode, things won't work, so we can provide only (U)nconstrained and (D)eny as options. And certain apps like grep, awk, sed, cp, and mkdir should always inherit the parent profile rather than having their own profile or running unconfined, so for them we can specify that only (I)nherit and (D)eny are the allowed options. Any programs that are not listed in the qualifiers section get the full (I)nherit / (P)rofile / (U)nconstrained / (D)eny option set. If the user is doing something tricky and wants different behavior, they can tweak or remove the corresponding line in the conf file. The B<[defaulthat]> section lists changehat-aware programs and what hat aa-logprof(1) will collapse the entries to for that program if the user specifies that the access should be allowed, but should not have it's own hat. The B<[globs]> section allows modification of the logprof rule engine with respect to globbing suggestions that the user will be prompted with. The format of each line is-- "Eperl globE = Eapparmor globE". When aa-logprof(1) asks about a specific path, if the perl glob matches the path, it replaces the part of the path that matched with the corresponding apparmor glob and adds it to the list of globbing suggestions. Lines starting with # are comments and are ignored. =head1 EXAMPLE [qualifiers] # things will very likely be painfully broken if bash has it's own profile /bin/bash = iu # mount doesn't work if it's confined /bin/mount = u # these helper utilities should inherit the parent profile and # shouldn't have their own profiles /bin/awk = i /bin/grep = i /bin/sed = i [defaulthat] /usr/sbin/sshd = EXEC /usr/sbin/httpd2 = DEFAULT_URI /usr/sbin/httpd2-prefork = DEFAULT_URI [globs] # /foo/bar/lib/libbaz.so -> /foo/bar/lib/lib* /lib/lib[^\/]+so[^\/]*$ = /lib/lib*so* # strip kernel version numbers from kernel module accesses ^/lib/modules/[^\/]+\/ = /lib/modules/*/ # strip pid numbers from /proc accesses ^/proc/\d+/ = /proc/*/ =head1 BUGS If you find any bugs, please report them at L. =head1 SEE ALSO apparmor(7), apparmor.d(5), aa-enforce(1), aa-complain(1), aa-disable(1), aa_change_hat(2), aa-logprof(1), aa-genprof(1), and L. =cut apparmor-2.13.3/utils/aa-decode.pod0000644000175000017500000000141213502024172014651 0ustar jjjj=pod =head1 NAME aa-decode - decode hex-encoded in AppArmor log files =head1 SYNOPSIS B [option] EHEX STRINGE =head1 DESCRIPTION B will decode hex-encoded strings as seen in AppArmor log output. It will also take an audit log on standard input and convert any hex-encoded AppArmor log entries and display them on standard output. =head1 OPTIONS =over 4 =item --help displays a short usage statement. =back =head1 EXAMPLES $ aa-decode 2F746D702F666F6F20626172 Decoded: /tmp/foo bar $ cat /var/log/kern.log | aa-decode ... denied_mask="r::" fsuid=1000 ouid=1000 name=/tmp/foo bar =head1 BUGS None. Please report any you find to Launchpad at L. =head1 SEE ALSO apparmor(7) =cut apparmor-2.13.3/utils/aa-status.pod0000644000175000017500000000654513502024172014765 0ustar jjjj# This publication is intellectual property of Novell Inc. and Canonical # Ltd. Its contents can be duplicated, either in part or in whole, provided # that a copyright label is visibly located on each copy. # # All information found in this book has been compiled with utmost # attention to detail. However, this does not guarantee complete accuracy. # Neither SUSE LINUX GmbH, Canonical Ltd, the authors, nor the translators # shall be held liable for possible errors or the consequences thereof. # # Many of the software and hardware descriptions cited in this book # are registered trademarks. All trade names are subject to copyright # restrictions and may be registered trade marks. SUSE LINUX GmbH # and Canonical Ltd. essentially adhere to the manufacturer's spelling. # # Names of products and trademarks appearing in this book (with or without # specific notation) are likewise subject to trademark and trade protection # laws and may thus fall under copyright restrictions. # =pod =head1 NAME aa-status - display various information about the current AppArmor policy. =head1 SYNOPSIS B [option] =head1 DESCRIPTION B will report various aspects of the current state of AppArmor confinement. By default, it displays the same information as if the I<--verbose> argument were given. A sample of what this looks like is: apparmor module is loaded. 110 profiles are loaded. 102 profiles are in enforce mode. 8 profiles are in complain mode. Out of 129 processes running: 13 processes have profiles defined. 8 processes have profiles in enforce mode. 5 processes have profiles in complain mode. Other argument options are provided to report individual aspects, to support being used in scripts. =head1 OPTIONS B accepts only one argument at a time out of: =over 4 =item --enabled returns error code if AppArmor is not enabled. =item --profiled displays the number of loaded AppArmor policies. =item --enforced displays the number of loaded enforcing AppArmor policies. =item --complaining displays the number of loaded non-enforcing AppArmor policies. =item --verbose displays multiple data points about loaded AppArmor policy set (the default action if no arguments are given). =item --json displays multiple data points about loaded AppArmor policy set in a JSON format, fit for machine consumption. =item --pretty-json same as --json, formatted to be readable by humans as well as by machines. =item --help displays a short usage statement. =back =head1 EXIT STATUS Upon exiting, B will set its exit status to the following values: =over 4 =item B<0> if apparmor is enabled and policy is loaded. =item B<1> if apparmor is not enabled/loaded. =item B<2> if apparmor is enabled but no policy is loaded. =item B<3> if the apparmor control files aren't available under /sys/kernel/security/. =item B<4> if the user running the script doesn't have enough privileges to read the apparmor control files. =back =head1 BUGS B must be run as root to read the state of the loaded policy from the apparmor module. It uses the /proc filesystem to determine which processes are confined and so is susceptible to race conditions. If you find any additional bugs, please report them at L. =head1 SEE ALSO apparmor(7), apparmor.d(5), and L. =cut apparmor-2.13.3/utils/logprof.conf.50000644000175000017500000001622113502024375015036 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "LOGPROF.CONF 5" .TH LOGPROF.CONF 5 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" logprof.conf \- configuration file for expert options that modify the behavior of the AppArmor aa\-logprof(1) program. .SH "DESCRIPTION" .IX Header "DESCRIPTION" The \fIaa\-logprof\fR\|(1) program can be configured to have certain default behavior by the contents of logprof.conf. .PP The \fB[qualifiers]\fR section lists specific programs that should have a subset of the full ix/px/ux list when asking what mode to execute it using. .PP Since creating a separate profile for /bin/bash is dangerous, we can specify that for /bin/bash, only (I)nherit, (U)nconstrained, and (D)eny should be allowed options and only those will show up in the prompt when we're asking about adding that to a profile. .PP Likewise, if someone currently exec's /bin/mount in ix or px mode, things won't work, so we can provide only (U)nconstrained and (D)eny as options. .PP And certain apps like grep, awk, sed, cp, and mkdir should always inherit the parent profile rather than having their own profile or running unconfined, so for them we can specify that only (I)nherit and (D)eny are the allowed options. .PP Any programs that are not listed in the qualifiers section get the full (I)nherit / (P)rofile / (U)nconstrained / (D)eny option set. .PP If the user is doing something tricky and wants different behavior, they can tweak or remove the corresponding line in the conf file. .PP The \fB[defaulthat]\fR section lists changehat-aware programs and what hat \&\fIaa\-logprof\fR\|(1) will collapse the entries to for that program if the user specifies that the access should be allowed, but should not have it's own hat. .PP The \fB[globs]\fR section allows modification of the logprof rule engine with respect to globbing suggestions that the user will be prompted with. .PP The format of each line is\*(-- \*(L" = \*(R". .PP When \fIaa\-logprof\fR\|(1) asks about a specific path, if the perl glob matches the path, it replaces the part of the path that matched with the corresponding apparmor glob and adds it to the list of globbing suggestions. .PP Lines starting with # are comments and are ignored. .SH "EXAMPLE" .IX Header "EXAMPLE" .Vb 3 \& [qualifiers] \& # things will very likely be painfully broken if bash has it\*(Aqs own profile \& /bin/bash = iu \& \& # mount doesn\*(Aqt work if it\*(Aqs confined \& /bin/mount = u \& \& # these helper utilities should inherit the parent profile and \& # shouldn\*(Aqt have their own profiles \& /bin/awk = i \& /bin/grep = i \& /bin/sed = i \& \& [defaulthat] \& /usr/sbin/sshd = EXEC \& /usr/sbin/httpd2 = DEFAULT_URI \& /usr/sbin/httpd2\-prefork = DEFAULT_URI \& \& [globs] \& # /foo/bar/lib/libbaz.so \-> /foo/bar/lib/lib* \& /lib/lib[^\e/]+so[^\e/]*$ = /lib/lib*so* \& \& # strip kernel version numbers from kernel module accesses \& ^/lib/modules/[^\e/]+\e/ = /lib/modules/*/ \& \& # strip pid numbers from /proc accesses \& ^/proc/\ed+/ = /proc/*/ .Ve .SH "BUGS" .IX Header "BUGS" If you find any bugs, please report them at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7), \fIapparmor.d\fR\|(5), \fIaa\-enforce\fR\|(1), \fIaa\-complain\fR\|(1), \&\fIaa\-disable\fR\|(1), \fIaa_change_hat\fR\|(2), \fIaa\-logprof\fR\|(1), \fIaa\-genprof\fR\|(1), and . apparmor-2.13.3/utils/logprof.conf.5.html0000644000175000017500000001063513502024376016005 0ustar jjjj
 

NAME

logprof.conf - configuration file for expert options that modify the behavior of the AppArmor aa-logprof(1) program.

DESCRIPTION

The aa-logprof(1) program can be configured to have certain default behavior by the contents of logprof.conf.

The [qualifiers] section lists specific programs that should have a subset of the full ix/px/ux list when asking what mode to execute it using.

Since creating a separate profile for /bin/bash is dangerous, we can specify that for /bin/bash, only (I)nherit, (U)nconstrained, and (D)eny should be allowed options and only those will show up in the prompt when we're asking about adding that to a profile.

Likewise, if someone currently exec's /bin/mount in ix or px mode, things won't work, so we can provide only (U)nconstrained and (D)eny as options.

And certain apps like grep, awk, sed, cp, and mkdir should always inherit the parent profile rather than having their own profile or running unconfined, so for them we can specify that only (I)nherit and (D)eny are the allowed options.

Any programs that are not listed in the qualifiers section get the full (I)nherit / (P)rofile / (U)nconstrained / (D)eny option set.

If the user is doing something tricky and wants different behavior, they can tweak or remove the corresponding line in the conf file.

The [defaulthat] section lists changehat-aware programs and what hat aa-logprof(1) will collapse the entries to for that program if the user specifies that the access should be allowed, but should not have it's own hat.

The [globs] section allows modification of the logprof rule engine with respect to globbing suggestions that the user will be prompted with.

The format of each line is-- "<perl glob> = <apparmor glob>".

When aa-logprof(1) asks about a specific path, if the perl glob matches the path, it replaces the part of the path that matched with the corresponding apparmor glob and adds it to the list of globbing suggestions.

Lines starting with # are comments and are ignored.

EXAMPLE

  [qualifiers]
    # things will very likely be painfully broken if bash has it's own profile
    /bin/bash  = iu

    # mount doesn't work if it's confined
    /bin/mount = u

    # these helper utilities should inherit the parent profile and
    # shouldn't have their own profiles
    /bin/awk   = i
    /bin/grep  = i
    /bin/sed   = i

  [defaulthat]
    /usr/sbin/sshd           = EXEC
    /usr/sbin/httpd2         = DEFAULT_URI
    /usr/sbin/httpd2-prefork = DEFAULT_URI

  [globs]
    # /foo/bar/lib/libbaz.so -> /foo/bar/lib/lib*
    /lib/lib[^\/]+so[^\/]*$  = /lib/lib*so*

    # strip kernel version numbers from kernel module accesses
    ^/lib/modules/[^\/]+\/   = /lib/modules/*/

    # strip pid numbers from /proc accesses
    ^/proc/\d+/              = /proc/*/

BUGS

If you find any bugs, please report them at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7), apparmor.d(5), aa-enforce(1), aa-complain(1), aa-disable(1), aa_change_hat(2), aa-logprof(1), aa-genprof(1), and https://wiki.apparmor.net.

 
apparmor-2.13.3/utils/aa-genprof.pod0000644000175000017500000000606113502024172015073 0ustar jjjj# This publication is intellectual property of Novell Inc. and Canonical # Ltd. Its contents can be duplicated, either in part or in whole, provided # that a copyright label is visibly located on each copy. # # All information found in this book has been compiled with utmost # attention to detail. However, this does not guarantee complete accuracy. # Neither SUSE LINUX GmbH, Canonical Ltd, the authors, nor the translators # shall be held liable for possible errors or the consequences thereof. # # Many of the software and hardware descriptions cited in this book # are registered trademarks. All trade names are subject to copyright # restrictions and may be registered trade marks. SUSE LINUX GmbH # and Canonical Ltd. essentially adhere to the manufacturer's spelling. # # Names of products and trademarks appearing in this book (with or without # specific notation) are likewise subject to trademark and trade protection # laws and may thus fall under copyright restrictions. # =pod =head1 NAME aa-genprof - profile generation utility for AppArmor =head1 SYNOPSIS BexecutableE> [I<-d /path/to/profiles>] [I<-f /path/to/logfile>]> =head1 OPTIONS B<-d --dir /path/to/profiles> Specifies where to look for the AppArmor security profile set. Defaults to /etc/apparmor.d. B<-f --file /path/to/logfile> Specifies the location of logfile. Default locations are read from F. Typical defaults are: /var/log/audit/audit.log /var/log/syslog /var/log/messages =head1 DESCRIPTION When running aa-genprof, you must specify a program to profile. If the specified program is not a fully-qualified path, aa-genprof will search $PATH in order to find the program. If a profile does not exist for the program, aa-genprof will create one using aa-autodep(1). Genprof will then: - set the profile to complain mode - write a mark to the system log - instruct the user to start the application to be profiled in another window and exercise its functionality It then presents the user with two options, (S)can system log for entries to add to profile and (F)inish. If the user selects (S)can or hits return, aa-genprof will parse the complain mode logs and iterate through generated violations using aa-logprof(1). After the user finishes selecting profile entries based on violations that were detected during the program execution, aa-genprof will reload the updated profiles in complain mode and again prompt the user for (S)can and (F)inish. This cycle can then be repeated as necessary until all application functionality has been exercised without generating access violations. When the user eventually hits (F)inish, aa-genprof will set the main profile, and any other profiles that were generated, into enforce mode and exit. =head1 BUGS If you find any bugs, please report them at L. =head1 SEE ALSO apparmor(7), apparmor.d(5), aa-enforce(1), aa-complain(1), aa-disable(1), aa_change_hat(2), aa-logprof(1), logprof.conf(5), and L. =cut apparmor-2.13.3/utils/aa-enforce.80000644000175000017500000001207213502024375014445 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "AA-ENFORCE 8" .TH AA-ENFORCE 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa\-enforce \- set an AppArmor security profile to enforce mode from being disabled or complain mode. .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-enforce \f(BI\fB [\f(BI\fB ...] [\f(BI\-d /path/to/profiles\fB] [\f(BI\-\-no\-reload\fB]\fR .SH "OPTIONS" .IX Header "OPTIONS" \&\fB\-d \-\-dir / path/to/profiles\fR .PP .Vb 2 \& Specifies where to look for the AppArmor security profile set. \& Defaults to /etc/apparmor.d. .Ve .PP \&\fB\-\-no\-reload\fR Do not reload the profile after modifying it. .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBaa-enforce\fR is used to set one or more profiles to \fIenforce\fR mode. This command is only relevant in conjunction with the \fIaa-complain\fR utility which sets a profile to complain mode and the \fIaa-disable\fR utility which unloads and disables a profile. The default mode for a security policy is enforce and the \fIaa-complain\fR utility must be run to change this behavior. .SH "BUGS" .IX Header "BUGS" If you find any bugs, please report them at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7), \fIapparmor.d\fR\|(5), \fIaa\-complain\fR\|(1), \fIaa\-disable\fR\|(1), \&\fIaa_change_hat\fR\|(2), and . apparmor-2.13.3/utils/aa-cleanprof.pod0000644000175000017500000000203113502024172015375 0ustar jjjj=pod =head1 NAME aa-cleanprof - clean an existing AppArmor security profile. =head1 SYNOPSIS BexecutableE> [IexecutableE> ...] [I<-d /path/to/profiles>] [I<--no-reload]> [I<-s>]> =head1 OPTIONS B<-d --dir /path/to/profiles> Specifies where to look for the AppArmor security profile set. Defaults to /etc/apparmor.d. B<--no-reload> Do not reload the profile after modifying it. B<-s --silent> Silently overwrites the profile without user prompt. =head1 DESCRIPTION B is used to perform a cleanup on one or more profiles. The tool removes any existing superfluous rules (rules that are covered under an include or another rule), reorders the rules to group similar rules together and removes all comments from the file. =head1 BUGS If you find any bugs, please report them at L. =head1 SEE ALSO apparmor(7), apparmor.d(5), aa-enforce(1), aa-complain(1), aa-disable(1), aa_change_hat(2), and L. =cut apparmor-2.13.3/utils/check_po.pl0000755000175000017500000000300413502024172014455 0ustar jjjj#!/usr/bin/perl # Look in the po directory and check the files for missing shortcuts - where the # msgid has a string "(B)lah" and the msgstr contains no character surrounded by # parens use Data::Dumper; my $dir = "./po"; opendir(PODIR, $dir) || die "Can't open directory $dir."; my $errors = {}; for my $file (grep { /.*\.po$/ && -f "$dir/$_" } readdir(PODIR)) { #print STDOUT "Processing $file\n"; check_po_for_shortcuts( "$dir/$file", $errors ); } my $msg = Data::Dumper->Dump([$errors], [qw(*ERRORS)]); my $count = 0; for my $f ( keys %$errors ) { for my $err ( keys %{$errors->{$f}} ) { $count++; } } print STDOUT "$count missing shortcuts in the po files\n.$msg\n"; closedir(PODIR); sub check_po_for_shortcuts { my ($filename, $errors) = @_; my $line = 0; if (open(PO, "$filename")) { while () { $line++; chomp; if ( /^.*msgid.*\(\w{1}?\)*/ ) { $looking_for_msgstr = 1; $msgid = $_; } if ( /^.*msgstr*/ && $looking_for_msgstr ) { unless (/^.*msgstr.*\(\w{1}?\)*/ or /^msgstr ""$/) { $errors->{$filename}{$line} = { "msgid" => $msgid, "msgstr" => $_, }; } $msgid = ""; $looking_for_msgstr = 0; } } close(PO); } return $config; } apparmor-2.13.3/utils/aa-unconfined.pod0000644000175000017500000000516613502024172015570 0ustar jjjj# This publication is intellectual property of Novell Inc. and Canonical # Ltd. Its contents can be duplicated, either in part or in whole, provided # that a copyright label is visibly located on each copy. # # All information found in this book has been compiled with utmost # attention to detail. However, this does not guarantee complete accuracy. # Neither SUSE LINUX GmbH, Canonical Ltd, the authors, nor the translators # shall be held liable for possible errors or the consequences thereof. # # Many of the software and hardware descriptions cited in this book # are registered trademarks. All trade names are subject to copyright # restrictions and may be registered trade marks. SUSE LINUX GmbH # and Canonical Ltd. essentially adhere to the manufacturer's spelling. # # Names of products and trademarks appearing in this book (with or without # specific notation) are likewise subject to trademark and trade protection # laws and may thus fall under copyright restrictions. # =pod =head1 NAME aa-unconfined - output a list of processes with tcp or udp ports that do not have AppArmor profiles loaded =head1 SYNOPSIS B] [I<--with-ss> | I<--with-netstat>]> =head1 OPTIONS =over 4 =item B<--paranoid> Displays all processes from F filesystem with tcp or udp ports that do not have AppArmor profiles loaded. =item B<--with-ss> Use the ss(8) command to find processes listening on network sockets (the default). =item B<--with-netstat> Use the netstat(8) command to find processes listening on network sockets. This is also what aa-unconfined will fall back to when ss(8) is not available. =back =head1 DESCRIPTION B will use netstat(8) to determine which processes have open network sockets and do not have AppArmor profiles loaded into the kernel. =head1 BUGS B must be run as root to retrieve the process executable link from the F filesystem. This program is susceptible to race conditions of several flavours: an unlinked executable will be mishandled; an executable started before an AppArmor profile is loaded will not appear in the output, despite running without confinement; a process that dies between the netstat(8) and further checks will be mishandled. This program only lists processes using TCP and UDP. In short, this program is unsuitable for forensics use and is provided only as an aid to profiling all network-accessible processes in the lab. If you find any bugs, please report them at L. =head1 SEE ALSO ss(8), netstat(8), apparmor(7), apparmor.d(5), aa_change_hat(2), and L. =cut apparmor-2.13.3/utils/aa-audit.8.html0000644000175000017500000000457213502024376015104 0ustar jjjj
 

NAME

aa-audit - set an AppArmor security profile to audit mode.

SYNOPSIS

aa-audit <executable> [<executable> ...] [-d /path/to/profiles] [--no-reload] [-r]

OPTIONS

-d --dir /path/to/profiles

   Specifies where to look for the AppArmor security profile set.
   Defaults to /etc/apparmor.d.

--no-reload Do not reload the profile after modifying it.

-r --remove

   Removes the audit mode for the profile.

DESCRIPTION

aa-audit is used to set one or more profiles to audit mode. In this mode security policy is enforced and all access (successes and failures) are logged to the system log.

The --remove option can be used to remove the audit mode for the profile.

BUGS

If you find any bugs, please report them at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7), apparmor.d(5), aa-enforce(1), aa-complain(1), aa-disable(1), aa_change_hat(2), and https://wiki.apparmor.net.

 
apparmor-2.13.3/utils/aa-mergeprof.8.html0000644000175000017500000000411613502024375015755 0ustar jjjj
 

NAME

aa-mergeprof - merge AppArmor security profiles.

SYNOPSIS

aa-mergeprof file [file ...] [-d /path/to/profiles]

OPTIONS

file

   One or more files containing profiles to merge into the profile directory (see -d).

-d --dir /path/to/profiles

   Specifies the target directory for the merged AppArmor security profile set.
   Defaults to /etc/apparmor.d.

DESCRIPTION

aa-mergeprof

BUGS

If you find any bugs, please report them at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7), apparmor.d(5), aa_change_hat(2), aa-genprof(1), aa-logprof(1), aa-enforce(1), aa-audit(1), aa-complain(1), aa-disable(1), and https://wiki.apparmor.net.

 
apparmor-2.13.3/utils/aa-logprof.pod0000644000175000017500000001506713502024172015111 0ustar jjjj# This publication is intellectual property of Novell Inc. and Canonical # Ltd. Its contents can be duplicated, either in part or in whole, provided # that a copyright label is visibly located on each copy. # # All information found in this book has been compiled with utmost # attention to detail. However, this does not guarantee complete accuracy. # Neither SUSE LINUX GmbH, Canonical Ltd, the authors, nor the translators # shall be held liable for possible errors or the consequences thereof. # # Many of the software and hardware descriptions cited in this book # are registered trademarks. All trade names are subject to copyright # restrictions and may be registered trade marks. SUSE LINUX GmbH # and Canonical Ltd. essentially adhere to the manufacturer's spelling. # # Names of products and trademarks appearing in this book (with or without # specific notation) are likewise subject to trademark and trade protection # laws and may thus fall under copyright restrictions. # =pod =head1 NAME aa-logprof - utility for updating AppArmor security profiles =head1 SYNOPSIS B] [I<-f /path/to/logfile>] [I<-m Emark in logfileE>]> =head1 OPTIONS B<-d --dir /path/to/profiles> Specifies where to look for the AppArmor security profile set. Defaults to /etc/apparmor.d. B<-f --file /path/to/logfile> Specifies the location of logfile that contains AppArmor security events. Default locations are read from F. Typical defaults are: /var/log/audit/audit.log /var/log/syslog /var/log/messages B< -m --logmark "mark"> aa-logprof will ignore all events in the system log before the specified mark is seen. If the mark contains spaces, it must be surrounded with quotes to work correctly. =head1 DESCRIPTION B is an interactive tool used to review AppArmor generated messages and update AppArmor security profiles. Running aa-logprof will scan the log file and if there are new AppArmor events that are not covered by the existing profile set, the user will be prompted with suggested modifications to augment the profile. When aa-logprof exits profile changes are saved to disk. If AppArmor is running, the updated profiles are reloaded and if any processes that generated AppArmor events are still running in the null-complain-profile, those processes are set to run under their proper profiles. =head2 Responding to AppArmor Events B will generate a list of suggested profile changes that the user can choose from, or they can create their own, to modifiy the permission set of the profile so that the generated access violation will not re-occur. The user is then presented with info about the access including profile, path, old mode if there was a previous entry in the profile for this path, new mode, the suggestion list, and given these options: (A)llow, (D)eny, (I)gnore, (N)ew, (G)lob last piece, (Q)uit If the AppArmor profile was in complain mode when the event was generated, the default for this option is (A)llow, otherwise, it's (D)eny. The (D)eny option adds a "deny" rule to the AppArmor profile, which silences logging. The (I)gnore option allows user to ignore the event, without making any changes to the AppArmor profile. The suggestion list is presented as a numbered list with includes at the top, the literal path in the middle, and the suggested globs at the bottom. If any globs are being suggested, the shortest glob is the selected option, otherwise, the literal path is selected. Picking includes from the list must be done manually. Hitting a numbered key will change the selected option to the corresponding numbered entry in the list. If the user selects (N)ew, they'll be prompted to enter their own globbed entry to match the path. If the user-entered glob does not match the path for this event, they'll be informed and have the option to fix it. If the user selects (G)lob last piece then, taking the currently selected option, aa-logprof will remove the last path element and replace it with /*. If the last path element already was /*, aa-logprof will go up a directory level and replace it with /**. This new globbed entry is then added to the suggestion list and marked as the selected option. So /usr/share/themes/foo/bar/baz.gif can be turned into /usr/share/themes/** by hitting "g" three times. If the user selects (A)llow, aa-logprof will take the current selection and add it to the profile, deleting other entries in the profile that are matched by the new entry. Adding r access to /usr/share/themes/** would delete an entry for r access to /usr/share/themes/foo/*.gif if it exists in the profile. If (Q)uit is selected at this point, aa-logprof will ignore all new pending accesses. After all of the accesses have been handled, logrof will write all updated profiles to the disk and reload them if AppArmor is running. =head2 New Process (Execution) Events If there are unhandled x accesses generated by the execve(2) of a new process, aa-logprof will display the parent profile and the target program that's being executed and prompt the user to select an execute modifier. These modifiers will allow a choice for the target to: have it's own profile (px), inherit the parent's profile (ix), run unconstrained (ux), or deny access for the target. See apparmor.d(5) for details. If there is a corresponding entry for the target in the qualifiers section of /etc/apparmor/logprof.conf, the presented list will contain only the allowed modes. The default option for this question is selected using this logic-- # if px mode is allowed and profile exists for the target # px is default. # else if ix mode is allowed # ix is default # else # deny is default aa-logprof will never suggest "ux" as the default. =head2 ChangeHat Events If unknown aa_change_hat(2) events are found, the user is prompted to add a new hat, if the events should go into the default hat for this profile based on the corresponding entry in the defaulthat section of logprof.conf, or if the following events that run under that hat should be denied altogether. =head2 Capability Events If there are capability accesses, the user is shown each capability access and asked if the capability should be allowed, denied, or if the user wants to quit. See capability(7) for details. =head1 BUGS If you find any bugs, please report them at L. =head1 SEE ALSO klogd(8), auditd(8), apparmor(7), apparmor.d(5), aa_change_hat(2), logprof.conf(5), aa-genprof(1), aa-enforce(1), aa-complain(1), aa-disable(1), and L. =cut apparmor-2.13.3/utils/aa-autodep.80000644000175000017500000001264613502024375014474 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "AA-AUTODEP 8" .TH AA-AUTODEP 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa\-autodep \- guess basic AppArmor profile requirements .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-autodep \f(BI\fB [\f(BI\fB ...] [\f(BI\-d /path/to/profiles\fB] [\f(BI\-f\fB]\fR .SH "OPTIONS" .IX Header "OPTIONS" \&\fB\-d \-\-dir /path/to/profiles\fR .PP .Vb 2 \& Specifies where to look for the AppArmor security profile set. \& Defaults to /etc/apparmor.d. .Ve .PP \&\fB\-f \-\-force\fR .PP .Vb 1 \& Overwrites any existing AppArmor profile for the executable with the generated minimal AppArmor profile. .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBaa-autodep\fR is used to generate a minimal AppArmor profile for a set of executables. This program will generate a profile for binary executable as well as interpreted script programs. At a minimum aa-autodep will provide a base profile containing a base include directive which includes basic profile entries needed by most programs. The profile is generated by recursively calling \fIldd\fR\|(1) on the executables listed on the command line. .PP The \fI\-\-force\fR option will overwrite any existing profile for the executable with the newly generated minimal AppArmor profile. .SH "BUGS" .IX Header "BUGS" This program does not perform full static analysis of executables, so the profiles generated are necessarily incomplete. If you find any bugs, please report them at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7), \fIapparmor.d\fR\|(5), \fIaa\-complain\fR\|(1), \fIaa\-enforce\fR\|(1), \fIaa\-disable\fR\|(1), \&\fIaa_change_hat\fR\|(2), and . apparmor-2.13.3/utils/notify.conf0000644000175000017500000000150513502024172014525 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2010 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ # Set to 'no' to disable AppArmor notifications globally show_notifications="yes" # OPTIONAL - restrict using aa-notify to users in the given group # (if not set, everybody who has permissions to read the logfile can use it) # use_group="admin" # OPTIONAL - custom notification message body # message_body="This is a custom notification message." # OPTIONAL - custom notification message footer # message_footer="For more information visit https://foo.com" apparmor-2.13.3/utils/po/0000755000175000017500000000000013502024172012763 5ustar jjjjapparmor-2.13.3/utils/po/ug.po0000644000175000017500000005707313502024172013752 0ustar jjjj# Uyghur translation for apparmor # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: apparmor\n" "Report-Msgid-Bugs-To: AppArmor list \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2015-11-28 12:40+0000\n" "Last-Translator: AppArmor list \n" "Language-Team: Uyghur \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: ug\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "" #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "" #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "" #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" #: ../aa-genprof:147 msgid "Profiling" msgstr "" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "" #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "" #: ../aa-mergeprof:31 msgid "your profile" msgstr "" #: ../aa-mergeprof:32 msgid "base profile" msgstr "" #: ../aa-mergeprof:33 msgid "other profile" msgstr "" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "" #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "" #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "" #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "" #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "" #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "" #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "" #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "" #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "" #: ../aa-audit:26 msgid "remove audit mode" msgstr "" #: ../aa-audit:28 msgid "Show full trace" msgstr "" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "" #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "" #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "" #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "" #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "" #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "" #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "" #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "" #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "" #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "" #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "" #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "" #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "" #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "" #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "" #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "" #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "" #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "" #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "" #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "" #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "" #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "" #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "" apparmor-2.13.3/utils/po/ru.po0000644000175000017500000010527013502024172013756 0ustar jjjj# Russian translation for apparmor # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: apparmor-utils\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2016-03-29 16:04+0000\n" "Last-Translator: Eugene Roskin \n" "Language-Team: Russian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: ru\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "Создать профиль для заданной программы" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "расположение профилей" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "расположение файла журнала" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "имя программы для профилирования" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "Файл журнала %s не существует. Проверьте адрес расположения файла" #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" "Вероятно AppArmor не выполняется. Пожалуйста, включите AppArmor и повторите " "снова." #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "%s не является каталогом." #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "%s не существует, проверьте путь." #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" "\n" "Перед тем как начать, вы можете проверить\n" "существование профиля для приложения,\n" "которое вы хотите ограничить. Дополнительная\n" "информация содержится на веб-сайте:" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" "Пожалуйста, запустите требуемое для\n" "профилирования приложения в другом окне\n" "и проверьте его работоспособность.\n" "\n" "После завершения, выберите параметр \"Scan\",\n" "чтобы проверить события AppArmor в \n" "системном журнале. \n" "\n" "Для каждого события AppArmor, вам будет дана\n" "возможность выбора делегирования доступа\n" "или отказа в доступе." #: ../aa-genprof:147 msgid "Profiling" msgstr "Профилирование" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" "\n" "Повторная загрузка профилей AppArmor в принудительном режиме." #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" "\n" "Пожалуйста, поделитесь вашим новым профилем!\n" "Дополнительные сведения на веб-сайте:" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "Создание профиля %s завершено." #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "Обработать записи журнала для создания профилей" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "отметить в журнале, чтобы начать обработку после" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "Очистить профили для заданных программ" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "имя программы" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "Заменить чистым профилем без запросов" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "Выполнить двух или трёхэтапное объединение заданных профилей" #: ../aa-mergeprof:31 msgid "your profile" msgstr "ваш профиль" #: ../aa-mergeprof:32 msgid "base profile" msgstr "базовый профиль" #: ../aa-mergeprof:33 msgid "other profile" msgstr "другой профиль" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "" "Следующие локальные профили изменены. Вы действительно хотите сохранить их?" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "Расположение" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "Выберите соответствующий режим" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "Неизвестный выбор" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "Файл включает" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "Укажите, что вы хотите добавить" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "Прикрепление %s к файлу." #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "неизвестно" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "Удалены %s предыдущие совпадающие записи профиля." #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "Профиль" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "Добавление %s в профиль." #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "" #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "" #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "(разрешения владельца отключены)" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "(принудительно назначить новые разрешения владельцу)" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "Устаревший режим" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "Новый режим" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "Режим" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "Добавление %(path)s %(mod)s в профиль" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "Введите новый адрес: " #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "Тип Socket" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "Добавление %s в профиль" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "Добавление сетевого доступа %(family)s %(type)s в профиль." #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "Отказ в сетевом доступе %(family)s %(type)s к профилю" #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "Создать базовый профиль AppArmor по предполагаемым требованиям" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "заменить существующий профиль" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "Переключить заданные программы в режим аудита" #: ../aa-audit:26 msgid "remove audit mode" msgstr "удалить режим аудита" #: ../aa-audit:28 msgid "Show full trace" msgstr "Показать полноценное отслеживание" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "Переключить заданную программу в претензионный режим" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "Переключить заданную программу в принудительный режим" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "Отключить профиль для заданных программ" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "Список процессов без ограничений с портами TCP и UDP" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "проверить все процессы /proc" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "%(pid)s %(program)s (%(commandline)s) не имеет ограничений" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "%(pid)s %(program)s%(pname)s не имеет ограничений" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "%(pid)s %(program)s (%(commandline)s) ограничены '%(attribute)s'" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "%(pid)s %(program)s%(pname)s ограничены '%(attribute)s'" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "Невозможно найти %s" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "Назначение %s претензионного режима." #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "Назначение %s принудительного режима." #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "" #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "Невозможно создать %(link)s символическую ссылку %(filename)s." #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "Невозможно прочитать первую строку %s: Файл не найден" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" "Вы действительно хотите отменить этот набор изменений профиля и выйти?" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "Отмена всех изменений." #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "Соединение с репозиторием..." #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "ВНИМАНИЕ: Ошибка загрузки профилей из репозитория" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "Ошибка задействования профилей: %s" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "%s не содержит профиль" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" "ВНИМАНИЕ: Ошибка синхронизации профилей с репозиторием:\n" "%s\n" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" "ВНИМАНИЕ: Ошибка синхронизации профилей с репозиторием\n" "%s" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" "ВНИМАНИЕ: Обнаружена ошибка во время выгрузки профиля %(profile)s\n" "%(ret)s" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "Изменения выгружены в репозиторий." #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "Запись списка изменений: " #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" "Ошибка репозитория\n" "Регистрация или вход не выполнены. Реквизиты\n" "для выполнения входа необходимы для выгрузки\n" "профилей в репозиторий. Изменения не отправлены." #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "Конечный профиль существует: %s\n" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "Программа" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "Выполнить" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "Вы действительно указали переход на локальный профиль?" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "Введите имя профиля на который требуется перейти: " #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" "Необходимо ли AppArmor санировать среду\n" "при переключении профилей?\n" "\n" "Санирование среды наиболее безопасно,\n" "но некоторые приложения зависят от\n" "наличия LD_PRELOAD или LD_LIBRARY_PATH." #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" "Необходимо ли AppArmor санировать среду\n" "при переключении профилей?\n" "\n" "Санирование среды наиболее безопасно,\n" "но это приложение использует LD_PRELOAD\n" "или LD_LIBRARY_PATH, т.о. санирование среды\n" "может привести к неполадкам в его работе." #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" "Запуск процессов в режиме без ограничений\n" "крайне опасно и может привести к появлению\n" "брешей в системе безопаности.\n" "\n" "Вы действительно хотите удалить все элементы\n" "защиты AppArmor во время выполнения %s ?" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" "Необходимо ли AppArmor санировать среду\n" "во время выполнения этой программы в\n" "режиме без ограничений?\n" "\n" "Не проводя санацию среды во время \n" "открытия программы в режиме без \n" "ограничений, может привести к\n" "появлению брешей в безопасности\n" "системы, чего следует избегать." #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" "Профиль для %s не существует.\n" "Вы действительно хотите создать его?" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "Изменения претензионного режима:" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "Изменения принудительного режима:" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "Обнаружен недопустимый режим: %s" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "Добавление %(path)s %(mode)s в профиль" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" "Указанный адрес расположения не соответствует \n" "этой записи журнала:\n" "\n" " Запись журнала: %(path)s\n" " Введённый адрес: %(ans)s\n" "Вы действительно хотите использовать этот \n" "адрес расположения?" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "Считывание записей журнала из %s." #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "Обновление профилей AppArmor в %s." #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" "Укажите, какие изменения профиля вы хотите \n" "сохранить в локальный набор профилей." #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "Изменения локального профиля" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "Изменения профиля" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "Невозможно найти существующий профиль %s для сравнения изменений." #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "Невозможно считать профили AppArmor в %s" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" "Профиль %(profile)s в %(file)s содержит синтаксические ошибки в строке: " "%(line)s." #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "Недопустимый режим %(mode)s в файле: %(file)s в строке: %(line)s" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "" #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "" #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "" #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "" #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "" #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "Назначение %s режима аудита." #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "Удаление режима аудита из %s." #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "Профиль для %s уже существует - пропуск." #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" "Локальный профиль %(program)s в файле %(file)s был изменён. Вы действительно " "хотите сохранить его?" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "Профиль для %s не существует. Очистка не требуется." #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "Недопустимая клавиша быстрого доступа для" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "(Y)Да" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "(N)Нет" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "(C)Отмена" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "(A)Разрешить" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "(M)Подробнее" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "(Т)Аудит" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "(Т)Аудит отключён" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "(Т) Аудит всего" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "(O)Разрешения владельца действуют" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "(O)Разрешения владельца не действуют" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "(D)Отказать" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "(R)Прервать" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "(F)Завершить" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "(P)Профиль" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "(P)Выполнить очистку профиля" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "(C)Выполнить очистку потомка" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "(C)Продолжить профилирование" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "(S)Проверить системный журнал с событиями AppArmor" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "(H)Справка" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "(V)Обзор профиля" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "(U)Задействовать профиль" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "(C)Создать новый профиль" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "(U)Обновить профиль" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "(I)Пропустить обновление" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "Сохранить (T)выбранный профиль" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "(U)Выгрузить изменения" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "(V)Просмотреть изменения" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "(E)Задействовать репозиторий" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "(D)Выключить репозиторий" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "(N)Не спрашивать в дальнейшем" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "Спросить меня (L)позднее" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "(O)Заменить профиль" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "(K)Сохранить профиль" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "(C)Продолжить" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "(I)Пропустить" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "" #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "" #, python-format #~ msgid "Adding network access %s %s to profile." #~ msgstr "Добавление сетевого доступа %s %s в профиль." apparmor-2.13.3/utils/po/fr.po0000644000175000017500000006020013502024172013730 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-utils\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2013-11-15 02:39+0000\n" "Last-Translator: Novell Language \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: fr\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "" #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "" #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "" #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" #: ../aa-genprof:147 msgid "Profiling" msgstr "Création de profil" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "Génération du profil terminé pour %s." #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "" #: ../aa-mergeprof:31 msgid "your profile" msgstr "" #: ../aa-mergeprof:32 msgid "base profile" msgstr "" #: ../aa-mergeprof:33 msgid "other profile" msgstr "" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "Chemin d'accès" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "" #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "%s entrées de profil précédemment correspondantes supprimées." #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "Profil" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "Mode compatibilité" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "Gravité" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "" #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "Ajout de capacité %s au profil." #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "Refus de capacité %s au profil." #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "(autorisations du propriétaire désactivées)" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "(forcer les nouvelles autorisations pour le propriétaire)" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "(forcer toutes les autorisations de règles pour le propriétaire)" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "Ancien mode" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "Nouveau mode" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "(forcer les autorisations pour le propriétaire)" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "Mode" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "Saisissez le nouveau chemin : " #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "Famille d'adresses réseau" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "Type de socket" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "" #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "" #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "" #: ../aa-audit:26 msgid "remove audit mode" msgstr "" #: ../aa-audit:28 msgid "Show full trace" msgstr "" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "" #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "" #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "" #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "" #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "" #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "" #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "" #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "" #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "" #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "" #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "" #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "" #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "" #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "" #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "" #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "" #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "" #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "" #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "" #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "" #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "" #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "" #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "" #, python-format #~ msgid "Adding network access %s %s to profile." #~ msgstr "Ajout de l'accès réseau %s %s au profil." apparmor-2.13.3/utils/po/apparmor-utils.pot0000644000175000017500000005664313502024172016504 0ustar jjjj# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR NOVELL, Inc. # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "" #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "" #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "" #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" #: ../aa-genprof:147 msgid "Profiling" msgstr "" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "" #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "" #: ../aa-mergeprof:31 msgid "your profile" msgstr "" #: ../aa-mergeprof:32 msgid "base profile" msgstr "" #: ../aa-mergeprof:33 msgid "other profile" msgstr "" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "The following local profiles were changed. Would you like to save them?" msgstr "" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "" #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "" #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "" #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "" #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "" #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "" #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "" #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "" #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "" #: ../aa-audit:26 msgid "remove audit mode" msgstr "" #: ../aa-audit:28 msgid "Show full trace" msgstr "" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "" #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "" #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "" #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "" #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "" #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "" #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "" #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "" #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "" #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "" #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "" #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "" #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "" #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "" #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "" #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in /etc/apparmor/logprof." "conf." msgstr "" #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "" #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "" #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "" #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "" #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "" #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "" #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "" #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "" apparmor-2.13.3/utils/po/it.po0000644000175000017500000006155013502024172013746 0ustar jjjj# Italian translation for apparmor # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: apparmor\n" "Report-Msgid-Bugs-To: AppArmor list \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2014-10-27 20:25+0000\n" "Last-Translator: Milo Casagrande \n" "Language-Team: Italian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: it\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "Genera profilo per il programma fornito" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "percorso ai profili" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "percorso a file registro" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "nome del programma per il profilo" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "Il file di registro %s non esiste: controllare il percorso" #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" "AppArmor non sembra essere stato avviato: abilitare AppArmor e riprovare." #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "%s non è una directory." #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" "Impossibile trovare %(profiling)s nell'elenco dei percorsi di sistema. Se il " "nome\n" "dell'applicazione è corretto, eseguire \"which %(profiling)s\", come utente " "con la\n" "variable PATH impostata correttamente, per trovare il percorso completo\n" "da utilizzare come parametro." #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "%s non esiste: controllare il percorso." #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" "\n" "Prima di iniziare, verificare se esiste già\n" "un profilo per l'applicazione da isolare.\n" "Per maggiori informazioni consultare\n" "la seguente pagina wiki:" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" #: ../aa-genprof:147 msgid "Profiling" msgstr "Raccolta profilo" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "Creazione profilo per %s completata." #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "Pulisce i profili per i programmi forniti" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "nome del programma" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "Esegue unione a 2 o 3 vie sui profili forniti" #: ../aa-mergeprof:31 msgid "your profile" msgstr "proprio profilo" #: ../aa-mergeprof:32 msgid "base profile" msgstr "profilo base" #: ../aa-mergeprof:33 msgid "other profile" msgstr "altro profilo" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "I seguenti file locali sono stati modificati: salvarli?" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "Percorso" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "Selezione sconosciuta" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "Selezionare quelli da aggiungere" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "Aggiunta di %s al file" #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "sconosciuto" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "" #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "Profilo" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "Capacità" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "Severità" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "Aggiunta di %s al profilo." #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "Aggiunta capacità %s al profilo." #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "" #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "Modalità precedente" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "Modalità nuova" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "Modalità" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "Inserire nuovo percorso: " #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "Famiglia di rete" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "Tipo di socket" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "Aggiunta di %s al profilo" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "" #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "" #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "" #: ../aa-audit:26 msgid "remove audit mode" msgstr "" #: ../aa-audit:28 msgid "Show full trace" msgstr "" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "" #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "" #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "" #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "" #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "" #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "" #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "" #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "" #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "" #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "" #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "" #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "" #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "" #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "" #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "" #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "" #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "" #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "" #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "" #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "" #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "" #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "" #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "" apparmor-2.13.3/utils/po/bs.po0000644000175000017500000005707313502024172013743 0ustar jjjj# Bosnian translation for apparmor # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: apparmor-utils\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2013-11-14 23:32+0000\n" "Last-Translator: Steve Beattie \n" "Language-Team: Bosnian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: bs\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "" #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "" #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "" #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" #: ../aa-genprof:147 msgid "Profiling" msgstr "Profilisanje" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "" #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "" #: ../aa-mergeprof:31 msgid "your profile" msgstr "" #: ../aa-mergeprof:32 msgid "base profile" msgstr "" #: ../aa-mergeprof:33 msgid "other profile" msgstr "" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "" #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "" #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "" #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "" #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "" #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "" #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "" #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "" #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "" #: ../aa-audit:26 msgid "remove audit mode" msgstr "" #: ../aa-audit:28 msgid "Show full trace" msgstr "" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "" #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "" #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "" #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "" #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "" #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "" #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "" #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "" #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "" #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "" #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "" #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "" #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "" #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "" #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "" #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "" #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "" #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "" #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "" #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "" #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "" #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "" #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "" apparmor-2.13.3/utils/po/es.po0000644000175000017500000006005413502024172013737 0ustar jjjj# Spanish translation for apparmor # Copyright (c) 2017 Rosetta Contributors and Canonical Ltd 2017 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2017. # msgid "" msgstr "" "Project-Id-Version: apparmor\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2019-06-09 14:14+0000\n" "Last-Translator: Paco Molinero \n" "Language-Team: Spanish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-06-10 04:32+0000\n" "X-Generator: Launchpad (build 18978)\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "" #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "" #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "" #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" #: ../aa-genprof:147 msgid "Profiling" msgstr "" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "" #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "nombre del programa" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "" #: ../aa-mergeprof:31 msgid "your profile" msgstr "su perfil" #: ../aa-mergeprof:32 msgid "base profile" msgstr "" #: ../aa-mergeprof:33 msgid "other profile" msgstr "otro perfil" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "Ruta" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "Selección desconocida" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "Archivos incluidos" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "" #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "desconocido" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "" #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "" #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "" #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "" #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "Modo nuevo" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "Modo" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "" #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "" #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "" #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "" #: ../aa-audit:26 msgid "remove audit mode" msgstr "" #: ../aa-audit:28 msgid "Show full trace" msgstr "" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "Cambia el programa dado al modo reclamar" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "Estableciendo %s al modo reclamar." #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "" #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "" #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "" #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" "¿Confirma que quiere abandonar este conjunto de cambios de perfil y salir?" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "" #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "Conectando con el repositorio…" #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "Error al activar los perfiles: %s" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "%s no contiene ningún perfil" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "" #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "" #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "Programa" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "Ejecutar" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "" #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "" #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "" #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "Cambios del perfil" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "" #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "" #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "" #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "No se puede encontrar el perfil existente para modificarlo" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "" #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "No se encuentra el archivo: %s" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "" #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "" #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "" #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "" #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "" #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "" #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "(N)o" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "(C)ancelar" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "(M)ás" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "(F)inalizar" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "(N)uevo" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "(V)er" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "(C)ontinuar" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "(I)gnorar" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "" #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "" apparmor-2.13.3/utils/po/sv.po0000644000175000017500000007757213502024172013775 0ustar jjjj# Swedish translation for apparmor # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: apparmor\n" "Report-Msgid-Bugs-To: AppArmor list \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2019-05-26 08:20+0000\n" "Last-Translator: Jonatan Nyberg \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-05-27 05:35+0000\n" "X-Generator: Launchpad (build 18968)\n" "Language: sv\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "Generera profil för det givna programet" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "sökväg till profiler" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "sökväg till loggfil" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "namn på program att profilera" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "Loggfilen %s existerar inte. Vänligen kontrollera sökvägen." #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" "Det verkar som AppArmor inte startades. Vänligen aktivera AppArmor och " "försök igen." #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "%s är inte en katalog." #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" "Det går inte att hitta %(profiling)s i systemsökvägs listan. Om namnet på " "programmet\n" "är korrekt, kör \"vilken %(profiling)s\" som en användare med rätt SÖKVÄGS-" "\n" "miljön som inrättats för att hitta den fullt kvalificerade sökvägen och\n" "använd hela sökvägen som parameter." #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "%s finns inte, dubbelkolla sökvägen." #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" "\n" "Innan du börjar kan du kontrollera om en\n" "profil finns redan för programmet du\n" "vill begränsa. Se följande wikisida för\n" "mer information:" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" "Vänligen starta programmet som ska profileras i\n" "ett annat fönster och utöva dess funktionalitet nu.\n" "\n" "När du är klar väljer du alternativet \"Skanna\" nedan i \n" "för att skanna systemloggar för AppArmor-händelser. \n" "\n" "För varje AppArmor-händelse får du \n" "möjlighet att välja om åtkomst ska \n" "tillåtas eller nekas." #: ../aa-genprof:147 msgid "Profiling" msgstr "Profilering" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" "\n" "Överväga att bidra med din nya profil!\n" "Se följande wikisida för mer information:" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "Färdig med att generera profil för %s." #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "Processloggposter för att generera profiler" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "markera i loggen för att börja bearbetning efter" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "Rensa profilerna för de angivna programmen" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "programnamn" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "Skriv tyst över med en ren profil" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "Utför en 2-vägs- eller 3-vägssammanslutning på de angivna profilerna" #: ../aa-mergeprof:31 msgid "your profile" msgstr "din profil" #: ../aa-mergeprof:32 msgid "base profile" msgstr "basprofil" #: ../aa-mergeprof:33 msgid "other profile" msgstr "annan profil" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "Följande lokala profiler ändrades. Vill du spara dem?" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "Sökväg" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "Välj lämpligt läge" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "Okänt val" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "Filen inkluderar" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "Välj de du vill lägga till" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "Lägger till %s i filen." #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "okänd" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "Tog bort %s tidigare matchande profilposter." #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "Profil" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "Förmåga" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "Allvarlighet" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "Lägger till %s till profilen." #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "Lägger till förmåga %s till profilen." #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "Avvisa förmåga %s till profilen." #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "(ägarbehörighet av)" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "Gammalt läge" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "Nytt läge" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "Läge" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "Lägger till %(path)s %(mod)s till profilen" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "Ange ny sökväg: " #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "Nätverksfamilj" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "Uttagstyp" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "Lägger till %s till profilen" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "Lägger till nätverksåterkomst %(family)s %(type)s till profilen." #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "Nekar nätverksåtkomst %(family)s %(type)s till profilen." #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "Skapa en grundläggande AppArmor-profil genom att gissa krav" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "skriv över befintlig profil" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "Växla de angivna programmen till revisionsläge" #: ../aa-audit:26 msgid "remove audit mode" msgstr "ta bort revisionsläge" #: ../aa-audit:28 msgid "Show full trace" msgstr "Visa fullständigt spår" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "Växla det angivna programmet till klagläget" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "Inaktivera profilen för de angivna programmen" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "Listar obegränsade processer som har tcp- eller udp-portar" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "skanna alla processer från /proc" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "%(pid)s %(program)s (%(commandline)s) inte begränsad" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "%(pid)s %(program)s%(pname)s inte begränsad" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "%(pid)s %(program)s (%(commandline)s) begränsad av '%(attribute)s'" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "%(pid)s %(program)s%(pname)s begränsad av '%(attribute)s'" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "Följde för många länkar medan %s löstes" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "Kan inte hitta %s" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "Inställning %s till klagläge." #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "" #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "Det gick inte att hitta basnamnet för %s." #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "Kunde inte skapa %(link)s symlink till %(filename)s." #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "Det går inte att läsa första raden från %s: Filen hittades inte" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" "Är du säker på att du vill överge denna uppsättning profiländringar och " "avsluta?" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "Överge alla ändringar." #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "Anslutning till förråd..." #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "VARNING: Fel vid hämtning av profiler från förrådet" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "Fel vid aktivering av profiler: %s" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "%s innehåller ingen profil" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" "VARNING: Fel vid synkronisering av profiler med förrådet:\n" "%s\n" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" "VARNING: Fel vid synkronisering av profiler med förrådet:\n" "%s" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" "VARNING: Ett fel uppstod vid sändning av profilen %(profile)s\n" "%(ret)s" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "Skickade ändringar till förrådet." #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "Ändringsloggens post: " #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" "Förrådsfel\n" "Registrering eller inloggning misslyckades. Användarnamn\n" "information krävs för att skicka profiler till förrådet.\n" "Dessa ändringar kunde inte skickas." #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "Standard Hat" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "Förfrågad Hat" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "%s har övergångsnamn men inte övergångsläge" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "Målprofil finns: %s\n" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "Program" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "Kör" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "Anger du en övergång till en lokal profil?" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "Ange profilnamn för övergång till: " #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" "Ska AppArmor sanera miljön vid\n" "växling av profiler?\n" "\n" "Sanitisera miljö är säkrare,\n" "men vissa applikationer beror på närvaron\n" "av LD_PRELOAD or LD_LIBRARY_PATH." #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" "Ska AppArmor sanera miljön vid\n" "växling av profiler?\n" "\n" "Sanitisera miljö är säkrare,\n" "men denna applikation verkar använda LD_PRELOAD\n" "eller LD_LIBRARY_PATH och sanering av miljön\n" "kan orsaka funktionsproblem." #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" "Att starta processer i ett obegränsat tillstånd är mycket\n" "farlig operation och kan orsaka allvarliga säkerhetshål.\n" "\n" "Är du helt säker på att du vill ta bort allt\n" "AppArmor-skydd när du kör %s?" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" "Ska AppArmor sanera miljön när\n" "detta program körs obegränsat?\n" "\n" "Rengör inte miljön när obegränsning av\n" "ett program öppnar allvarliga säkerhetshål\n" "och bör undvikas om möjligt." #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" "En profil för% s existerar inte.\n" "Vill du skapa en?" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "Klaglägeändringar:" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "Ogiltigt läge hittades: %s" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "Lägger till %(path)s %(mode)s till profilen" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" "Den angivna sökvägen matchar inte denna loggpost:\n" "\n" " Loggpost: %(path)s\n" " Inmatad sökväg: %(ans)s\n" "Vill du verkligen använda den här sökvägen?" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "Läser loggposter från %s." #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "Uppdaterar AppArmor-profiler i %s." #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" "Välj vilken profiländringar du vill spara till\n" "lokal profiluppsättning." #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "Lokala profiländringar" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "Profiländringar" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "Kan inte hitta befintlig profil %s för att jämföra ändringar." #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "Kan inte läsa AppArmor-profiler i %s" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "%(profile)s profil i %(file)s innehåller syntaxfel i rad: %(line)s." #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" "Syntaxfel: Oväntad slut på profil som uppnåtts i filen: %(file)s rad: " "%(line)s" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" "Syntaxfel: Oväntad förmåga inmatning som finns i filen: %(file)s rad: " "%(line)s" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfel: Oväntad länkinmatning som finns i filen: %(file)s rad: %(line)s" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" "Syntaxfel: Oväntad ändringsprofilinmatning som finns i filen: %(file)s rad: " "%(line)s" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfel: Oväntad rlimit-post som finns i filen: %(file)s rad: %(line)s" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" "Syntaxfel: Oväntad boolean definition som finns i filen: %(file)s rad: " "%(line)s" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "Syntaxfel: Oväntad ledig filregeln i filen: %(file)s rad: %(line)s" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfel: Oväntad sökvägsinställning som finns i filen: %(file)s rad: " "%(line)s" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "Syntaxfel: Ogiltig regex %(path)s i filen: %(file)s rad: %(line)s" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "Ogiltigt läge %(mode)s i filen: %(file)s rad: %(line)s" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfel: Oväntad nätverksinmatning som finns i filen: %(file)s rad: " "%(line)s" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfel: Oväntad dbus-post som finns i filen: %(file)s rad: %(line)s" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfel: Oväntad monteringsinformation som finns i filen: %(file)s rad: " "%(line)s" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfel: Oväntad signalinmatning som finns i filen: %(file)s rad: %(line)s" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfel: Oväntad ptrace-post som finns i filen: %(file)s rad: %(line)s" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" "Syntaxfel: Oväntad pivot_root-post som finns i filen: %(file)s rad: %(line)s" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfel: Oväntad Unix-post som finns i filen: %(file)s rad: %(line)s" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" "Syntaxfel: Oväntade ändringshattdeklaration som hittades i filen: %(file)s " "rad: %(line)s" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" "Syntaxfel: oväntad hat-definition hittades i filen: %(file)s line: %(line)s" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "Fel: Multipla definitioner för hat %(hat)s i profilen %(profile)s." #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "Varning: ogiltig \"FÖRRÅD:\" rad i %s, ignorerar." #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "Syntaxfel: Okänd rad som hittades i filen: %(file)s rad: %(line)s" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" "Syntaxfel: saknas \"}\" eller \",\". Uppnått slutet av filen %(file)s medan " "inne i profilen %(profile)s" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "Omdefiniera befintlig variabel %(variable)s: %(value)s i %(file)s" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" "Värden läggs till i en existerande variabel %(variable)s: %(value)s i " "%(file)s" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" "Okänd variabel operation %(operation)s för variable %(variable)s i %(file)s" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "Ogiltig tillåten sträng: %(allow)s" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "Kan inte hitta befintlig profil för att ändra" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "Skrivar uppdaterad profil för %s." #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "Filen hittades inte: %s" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "Loggen innehåller okända läget %s" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "%s finns inte, dubbelkolla sökvägen." #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" "Det angivna programmet kan inte hittas, försök med programmets fullständiga " "sökväg: " #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "Profil för %s hittades inte, hoppar över" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "Inaktiverar %s." #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "Ställer in %s till granskningsläge." #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "Tar bort revisionsläge från %s." #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "Profilen för %s finns redan - hoppar över." #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" "\n" "Raderade regler för %s." #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" "Den lokala profilen för %(program)s i filen %(file)s ändrades. Vill du spara " "det?" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "Profilen för %s finns inte. Inget att rensa." #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "Ogiltig snabbtangent för" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "(J)a" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "(N)ej" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "(T)illåt" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "(M)er" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "(P)rofil" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "(X) ix På" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "(X) ix Av" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "(S)para ändringar" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "(N)y" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "(H)jälp" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "(V)isa profil" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "(U)ppdatera profil" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "(I)gnorera uppdatering" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "(V)isa ändringar" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "(V)isa" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "PromptUser: Okänt kommando %s" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "PromptUser: Dubbel snabbtangent för %(command)s: %(menutext)s " #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "PromptUser: Ogiltig snabbtangent i standardobjekt" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "PromptUser: Ogiltig standard %s" apparmor-2.13.3/utils/po/ko.po0000644000175000017500000005706313502024172013747 0ustar jjjj# Korean translation for apparmor # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: apparmor-utils\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2013-11-20 22:28+0000\n" "Last-Translator: AppArmor list \n" "Language-Team: Korean \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: ko\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "" #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "" #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "" #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" #: ../aa-genprof:147 msgid "Profiling" msgstr "" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "" #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "" #: ../aa-mergeprof:31 msgid "your profile" msgstr "" #: ../aa-mergeprof:32 msgid "base profile" msgstr "" #: ../aa-mergeprof:33 msgid "other profile" msgstr "" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "" #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "" #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "" #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "" #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "" #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "" #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "" #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "" #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "" #: ../aa-audit:26 msgid "remove audit mode" msgstr "" #: ../aa-audit:28 msgid "Show full trace" msgstr "" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "" #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "" #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "" #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "" #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "" #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "" #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "" #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "" #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "" #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "" #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "" #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "" #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "" #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "" #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "" #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "" #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "" #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "" #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "" #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "" #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "" #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "" #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "" apparmor-2.13.3/utils/po/pt_BR.po0000644000175000017500000005705113502024172014341 0ustar jjjj# Brazilian Portuguese translation for apparmor # Copyright (c) 2018 Rosetta Contributors and Canonical Ltd 2018 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2018. # msgid "" msgstr "" "Project-Id-Version: apparmor\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2018-12-03 23:25+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Brazilian Portuguese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "" #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "" #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "" #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" #: ../aa-genprof:147 msgid "Profiling" msgstr "" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "" #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "" #: ../aa-mergeprof:31 msgid "your profile" msgstr "" #: ../aa-mergeprof:32 msgid "base profile" msgstr "" #: ../aa-mergeprof:33 msgid "other profile" msgstr "" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "" #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "" #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "" #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "" #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "" #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "" #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "" #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "" #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "" #: ../aa-audit:26 msgid "remove audit mode" msgstr "" #: ../aa-audit:28 msgid "Show full trace" msgstr "" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "" #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "" #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "" #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "" #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "" #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "" #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "" #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "" #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "" #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "" #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "" #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "" #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "" #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "" #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "" #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "" #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "" #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "" #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "" #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "" #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "" #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "" #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "" apparmor-2.13.3/utils/po/pt.po0000644000175000017500000005715313502024172013761 0ustar jjjj# Portuguese translation for apparmor # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: apparmor\n" "Report-Msgid-Bugs-To: AppArmor list \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2016-03-03 11:01+0000\n" "Last-Translator: Ivo Xavier \n" "Language-Team: Portuguese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: po\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "caminho para perfis" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "" #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "%s não é um diretório." #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "" #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" #: ../aa-genprof:147 msgid "Profiling" msgstr "" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "" #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "" #: ../aa-mergeprof:31 msgid "your profile" msgstr "" #: ../aa-mergeprof:32 msgid "base profile" msgstr "" #: ../aa-mergeprof:33 msgid "other profile" msgstr "" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "" #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "" #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "" #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "" #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "" #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "" #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "" #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "" #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "" #: ../aa-audit:26 msgid "remove audit mode" msgstr "" #: ../aa-audit:28 msgid "Show full trace" msgstr "" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "" #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "" #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "" #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "" #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "" #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "" #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "" #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "" #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "" #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "" #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "" #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "" #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "" #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "" #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "" #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "" #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "" #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "" #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "" #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "" #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "" #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "" #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "" apparmor-2.13.3/utils/po/tr.po0000644000175000017500000005706713502024172013767 0ustar jjjj# Turkish translation for apparmor # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: apparmor\n" "Report-Msgid-Bugs-To: AppArmor list \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2014-05-21 18:45+0000\n" "Last-Translator: zeugma \n" "Language-Team: Turkish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: po\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "" #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "%s bir dizin değil" #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "" #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" #: ../aa-genprof:147 msgid "Profiling" msgstr "" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "" #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "" #: ../aa-mergeprof:31 msgid "your profile" msgstr "" #: ../aa-mergeprof:32 msgid "base profile" msgstr "" #: ../aa-mergeprof:33 msgid "other profile" msgstr "" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "" #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "" #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "" #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "" #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "" #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "" #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "" #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "" #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "" #: ../aa-audit:26 msgid "remove audit mode" msgstr "" #: ../aa-audit:28 msgid "Show full trace" msgstr "" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "" #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "" #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "" #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "" #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "" #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "" #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "" #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "" #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "" #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "" #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "" #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "" #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "" #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "" #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "" #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "" #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "" #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "" #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "" #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "" #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "" #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "" #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "" apparmor-2.13.3/utils/po/en_GB.po0000644000175000017500000010256113502024172014302 0ustar jjjj# English (United Kingdom) translation for apparmor # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: apparmor\n" "Report-Msgid-Bugs-To: AppArmor list \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2017-02-26 19:25+0000\n" "Last-Translator: Anthony Harrington \n" "Language-Team: English (United Kingdom) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: en_GB\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "Generate profile for the given program" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "path to profiles" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "path to logfile" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "name of program to profile" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "The logfile %s does not exist. Please check the path" #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" "It seems AppArmor was not started. Please enable AppArmor and try again." #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "%s is not a directory." #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "%s does not exists, please double-check the path." #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." #: ../aa-genprof:147 msgid "Profiling" msgstr "Profiling" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" "\n" "Reloaded AppArmor profiles in enforce mode." #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "Finished generating profile for %s." #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "Process log entries to generate profiles" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "mark in the log to start processing after" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "Cleanup the profiles for the given programs" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "name of program" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "Silently overwrite with a clean profile" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "Perform a 2-way or 3-way merge on the given profiles" #: ../aa-mergeprof:31 msgid "your profile" msgstr "your profile" #: ../aa-mergeprof:32 msgid "base profile" msgstr "base profile" #: ../aa-mergeprof:33 msgid "other profile" msgstr "other profile" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "" "The following local profiles were changed. Would you like to save them?" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "Path" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "Select the appropriate mode" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "Unknown selection" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "File includes" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "Select the ones you wish to add" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "Adding %s to the file." #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "unknown" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "Deleted %s previous matching profile entries." #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "Profile" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "Capability" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "Severity" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "Adding %s to profile." #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "Adding capability %s to profile." #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "Denying capability %s to profile." #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "(owner permissions off)" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "(force new perms to owner)" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "(force all rule perms to owner)" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "Old Mode" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "New Mode" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "(force perms to owner)" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "Mode" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "Adding %(path)s %(mod)s to profile" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "Enter new path: " #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "Network Family" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "Socket Type" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "Adding %s to profile" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "Adding network access %(family)s %(type)s to profile." #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "Denying network access %(family)s %(type)s to profile" #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "Generate a basic AppArmor profile by guessing requirements" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "overwrite existing profile" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "Switch the given programs to audit mode" #: ../aa-audit:26 msgid "remove audit mode" msgstr "remove audit mode" #: ../aa-audit:28 msgid "Show full trace" msgstr "Show full trace" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "Switch the given program to complain mode" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "Switch the given program to enforce mode" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "Disable the profile for the given programs" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "Lists unconfined processes having TCP or UDP ports" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "scan all processes from /proc" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "%(pid)s %(program)s (%(commandline)s) not confined" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "%(pid)s %(program)s%(pname)s not confined" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "Followed too many links while resolving %s" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "Can't find %s" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "Setting %s to complain mode." #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "Setting %s to enforce mode." #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "Unable to find basename for %s." #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "Could not create %(link)s symlink to %(filename)s." #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "Unable to read first line from %s: File Not Found" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" "Unable to fork: %(program)s\n" "\t%(error)s" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" "Are you sure you want to abandon this set of profile changes and exit?" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "Abandoning all changes." #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "Connecting to repository..." #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "WARNING: Error fetching profiles from the repository" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "Error activating profiles: %s" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "%s contains no profile" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" "WARNING: Error synchronising profiles with the repository:\n" "%s\n" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" "WARNING: Error synchronising profiles with the repository\n" "%s" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "Uploaded changes to repository." #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "Changelog Entry: " #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "Default Hat" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "Requested Hat" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "%s has transition name but not transition mode" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "Target profile exists: %s\n" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "Program" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "Execute" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "Are you specifying a transition to a local profile?" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "Enter profile name to transition to: " #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" "A profile for %s does not exist.\n" "Do you want to create one?" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "Complain-mode changes:" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "Enforce-mode changes:" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "Invalid mode found: %s" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "Adding %(path)s %(mode)s to profile" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "Reading log entries from %s." #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "Updating AppArmor profiles in %s." #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" "Select which profile changes you would like to save to the\n" "local profile set." #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "Local profile changes" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "Profile Changes" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "Can't find existing profile %s to compare changes." #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "Can't read AppArmor profiles in %s" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "Invalid mode %(mode)s in file: %(file)s line: %(line)s" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "Redefining existing variable %(variable)s: %(value)s in %(file)s" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "Invalid allow string: %(allow)s" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "Can't find existing profile to modify" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "Writing updated profile for %s." #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "File Not Found: %s" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "Log contains unknown mode %s" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "%s does not exist, please double-check the path." #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "Profile for %s not found, skipping" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "Disabling %s." #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "Setting %s to audit mode." #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "Removing audit mode from %s." #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "Profile for %s already exists - skipping." #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" "\n" "Deleted %s rules." #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "The profile for %s does not exists. Nothing to clean." #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "Invalid hotkey for" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "(Y)es" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "(N)o" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "(C)ancel" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "(A)llow" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "(M)ore" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "Audi(t)" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "Audi(t) off" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "Audit (A)ll" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "(O)wner permissions on" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "(O)wner permissions off" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "(D)eny" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "Abo(r)t" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "(F)inish" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "(I)nherit" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "(P)rofile" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "(P)rofile Clean Exec" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "(C)hild" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "(C)hild Clean Exec" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "(N)amed" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "(N)amed Clean Exec" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "(U)nconfined" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "(U)nconfined Clean Exec" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "(P)rofile Inherit" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "(P)rofile Inherit Clean Exec" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "(C)hild Inherit" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "(C)hild Inherit Clean Exec" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "(N)amed Inherit" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "(N)amed Inherit Clean Exec" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "(X) ix On" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "(X) ix Off" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "(S)ave Changes" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "(C)ontinue Profiling" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "(N)ew" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "(G)lob" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "Glob with (E)xtension" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "(A)dd Requested Hat" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "(U)se Default Hat" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "(S)can system log for AppArmor events" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "(H)elp" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "(V)iew Profile" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "(U)se Profile" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "(C)reate New Profile" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "(U)pdate Profile" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "(I)gnore Update" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "Save Selec(t)ed Profile" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "(U)pload Changes" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "(V)iew Changes" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "View Changes b/w (C)lean profiles" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "(V)iew" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "(E)nable Repository" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "(D)isable Repository" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "(N)ever Ask Again" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "Ask Me (L)ater" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "Allow All (N)etwork" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "Allow Network Fa(m)ily" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "(O)verwrite Profile" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "(K)eep Profile" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "(C)ontinue" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "(I)gnore" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "PromptUser: Unknown command %s" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "PromptUser: Invalid hotkey in default item" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "PromptUser: Invalid default %s" apparmor-2.13.3/utils/po/id.po0000644000175000017500000010470413502024172013725 0ustar jjjj# Indonesian translation for apparmor # Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2016. # msgid "" msgstr "" "Project-Id-Version: apparmor\n" "Report-Msgid-Bugs-To: AppArmor list \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2017-10-10 18:33+0000\n" "Last-Translator: Christian Boltz \n" "Language-Team: Indonesian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: id\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "Hasilkan profil untuk program yang diberikan" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "lokasi ke profil" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "lokasi ke logfile" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "nama program untuk profil" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "Logfile %s tidak ada. Silakan cek lokasinya." #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" "Sepertinya AppArmor tidak berjalan. Silakan aktifkan AppArmor dan coba lagi." #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "%s bukan direktori." #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" "Tidak dapat menemukan %(profiling)s di dalam daftar path sistem. Jika nama " "aplikasi\n" "sudah benar, silakan jalankan 'which %(profiling)s' sebagai pengguna dengan " "PATH\n" "environment yang benar untuk menemukan path yang memenuhi syarat dan\n" "gunakan path penuh sebagai parameter." #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "%s tidak ada, silakan cek kembali lokasinya." #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" "\n" "Sebelum memulai, Anda mungkin ingin mengecek jika\n" "sebuah profil telah ada untuk aplikasi yang ingin\n" "Anda batasi. Lihat halaman wiki berikut ini untuk\n" "informasi lebih lanjut:" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" "Silakan jalankan aplikasi untuk diprofilkan dalam\n" "jendela lain dan berlatih fungsinya sekarang.\n" "\n" "Setelah selesai, pilih \"Scan\" di bawah \n" "untuk memindai system logs untuk event AppArmor. \n" "\n" "Untuk tiap event AppArmor, Anda akan diberi \n" "kesempatan untuk memilih apakah akses \n" "harus diizinkan atau ditolak." #: ../aa-genprof:147 msgid "Profiling" msgstr "Memprofilkan" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" "\n" "Profil AppArmor dimuat ulang dalam mode paksa." #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" "\n" "Pertimbangkan untuk mengkontribusikan profil Anda!\n" "Lihat halaman wiki berikut untuk informasi lebih lanjut:" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "Selesai membuat profil untuk %s." #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "Entry log proses untuk membuat profil" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "tandai di dalam log untuk mulai memproses setelah" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "Bersihkan profil untuk program tersebut" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "nama program" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "Timpa dengan profil bersih secara hening" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "Lakukan penggabungan 2-arah atau 3-arah pada profil terkait" #: ../aa-mergeprof:31 msgid "your profile" msgstr "profil Anda" #: ../aa-mergeprof:32 msgid "base profile" msgstr "profil dasar" #: ../aa-mergeprof:33 msgid "other profile" msgstr "profil lain" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "Profil lokal berikut ini diubah. Apakah Anda ingin menyimpannya?" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "Jalur" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "Pilih mode yang sesuai" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "Pilihan tak diketahui" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "Berkas terkandung" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "Pilih yang Anda kehendaki untuk ditambahkan" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "Menambahkan %s ke dalam berkas." #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "tak diketahui" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "Menghapus %s entri profil sebelumnya yang cocok." #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "Profil" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "Kapabilitas" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "Kerumitan" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "Menambahkan %s ke dalam profil." #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "Menambahkan kapabilitas %s ke dalam." #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "Menolak kapabilitas %s ke dalam profil." #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "(izin pemilik tidak aktif)" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "(paksa izin baru ke pemilik)" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "(paksa semua izin aturan ke pemilik)" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "Mode Lama" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "Mode Baru" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "(paksa izin ke pemilik)" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "Mode" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "Menambahkan %(path)s %(mod)s ke profil" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "Masukkan jalur baru: " #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "Keluarga Jaringan" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "Jenis Soket" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "Menambahkan %s ke dalam profil" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "Menambahkan akses jaringan %(family)s %(type)s ke profil" #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "Menolak akses jaringan %(family)s %(type)s ke profil" #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "Hasilkan profil AppArmor dasar dengan menebak persyaratan" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "timpa profil saat ini" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "Ubah program ke dalam mode audit" #: ../aa-audit:26 msgid "remove audit mode" msgstr "hapus mode audit" #: ../aa-audit:28 msgid "Show full trace" msgstr "Tampilkan jejak penuh" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "Ubah program ke dalam mode komplain" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "Ubah program ke dalam mode desakan" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "Nonaktifkan profil pada program" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "Tampilkan proses tak terkekang yang memiliki port TCP atau UDP" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "pindai semua proses dari /proc" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "%(pid)s %(program)s (%(commandline)s) tidak terkekang" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "%(pid)s %(program)s%(pname)s tidak terkekang" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "%(pid)s %(program)s (%(commandline)s) terkekang oleh '%(attribute)s'" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "%(pid)s %(program)s%(pname)s terkekang oleh '%(attribute)s'" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "Mengikuti terlalu banyak tautan sementara menyelesaikan %s" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "Tidak dapat menemukan %s" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "Mengatur %s ke mode komplain." #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "Mengatur %s ke mode desakan." #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "Tak dapat menemukan nama dasar untuk %s." #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "Tak dapat menciptakan %(link)s symlink ke %(filename)s." #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "Tak dapat membaca baris pertama dari %s: File Not Found" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" "Tidak dapat mencabang: %(program)s\n" "\t%(error)s" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" "Apakah Anda yakin ingin meninggalkan perubahan set profil ini dan keluar?" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "Meninggalkan semua perubahan." #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "Menghubungkan ke repositori..." #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "PERINGATAN: Kesalahan mengambil profil dari repositori" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "Kesalahan mengaktifkan profil: %s" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "%s tidak berisi profil" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" "PERINGATAN: Kesalahan menyelaraskan profil dengan repositori:\n" "%s\n" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" "PERINGATAN: Kesalahan menyelaraskan profil dengan repositori:\n" "%s" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" "PERINGATAN: Sebuah kesalahan terjadi saat mengunggah profil %(profile)s\n" "%(ret)s" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "Menunggah perubahan ke repositori." #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "Entri Log Perubahan: " #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" "Kesalahan Repositori\n" "Pendaftaran atau upaya masuk tidak berhasil. Informasi login\n" "pengguna diperlukan untuk mengunggah profil ke repositori.\n" "Perubahan ini tidak dapat dikirim." #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "Topi Default" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "Topi yang Diminta" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "%s memiliki nama transisi tetapi bukan mode transisi" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "Profil target telah ada: %s\n" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "Program" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "Jalankan" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "Apakah Anda menentukan sebuah transisi ke profil lokal?" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "Masukkan nama profil untuk transisi ke: " #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" "Haruskah AppArmor membersihkan lingkungan saat\n" "beralih profil?\n" "\n" "Membersihkan lingkungan adalah lebih aman,\n" "tapi beberapa aplikasi tergantung pada kehadiran\n" "LD_PRELOAD atau LD_LIBRARY_PATH." #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" "Haruskah AppArmor membersihkan lingkungan saat\n" "beralih profil?\n" "\n" "Membersihkan lingkungan adalah lebih aman,\n" "tapi aplikasi ini nampaknya menggunakan LD_PRELOAD\n" "atau LD_LIBRARY_PATH dan membersihkan lingkungan\n" "dapat menimbulkan masalah fungsional." #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" "Menjalankan proses dalam keadaan tak terkekang adalah operasi\n" "yang sangat berbahaya dan dapat menimbulkan lubang keamanan serius.\n" "\n" "Apakah Anda yakin ingin menghapus semua proteksi\n" "AppArmor saat menjalankan %s ?" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" "Haruskah AppArmor membersihkan lingkungan saat\n" "menjalankan program tak terkekang?\n" "\n" "Tidak membersihkan lingkungan saat tidak mengekang\n" "program membuka lubang keamanan yang signifikan\n" "dan seharusnya sebisa mungkin dihindari." #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" "Sebuah profil untuk %s tidak ada.\n" "Apakah Anda ingin menciptakannya?" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "Mode komplain mengubah:" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "Mode desakan mengubah:" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "Mode tidak sah ditemukan: %s" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "Menambahkan %(path)s %(mode)s ke dalam profil" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" "Jalur yang ditentukan tidak cocok dengan entri log:\n" "\n" " Entri Log: %(path)s\n" " Jalur yang dimasukkan: %(ans)s\n" "Apakah Anda ingin menggunakan jalur ini?" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "Membaca entri log dari %s." #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "Memperbarui profil AppArmor di %s." #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" "Pilih perubahan profil mana yang Anda ingin simpan\n" "ke set profil lokal." #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "Peribahan profil lokal" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "Perubahan Profil" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "" "Tak dapat menemukan profil yang telah ada %s untuk membandingkan perubahan." #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "Tak dapat membaca profil AppArmor di %s" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" "Profil %(profile)s di %(file)s berisi kesalahan sintaksis pada baris: " "%(line)s." #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" "Kesalahan Sintaksis: Akhir Profil yang tak diharapkan ditemukan pada berkas: " "%(file)s baris: %(line)s" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" "Kesalahan Sintaksis: Entri kapabilitas yang tak diharapkan ditemukan pada " "berkas: %(file)s baris: %(line)s" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" "Kesalahan Sintaksis: Entri tautan yang tak diharapkan ditemukan pada berkas: " "%(file)s baris: %(line)s" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" "Kesalahan Sintaksis: Entri perubahan profil yang tak diharapkan ditemukan " "pada berkas: %(file)s baris: %(line)s" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" "Kesalahan Sintaksis: Entri rlimit yang tak diharapkan ditemukan pada berkas: " "%(file)s baris: %(line)s" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" "Kesalahan Sintaksis: Definisi boolean yang tak diharapkan ditemukan pada " "berkas: %(file)s baris: %(line)s" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" "Kesalahan Sintaksis: Aturan berkas polos yang tak diharapkan ditemuka pada " "berkas: %(file)s baris: %(line)s" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" "Kesalahan Sintaksis: Entri jalur yang tak diharapkan ditemukan pada berkas: " "%(file)s baris: %(line)s" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" "Kesalahan Sintaksis: Regex tidak sah %(path)s di berkas: %(file)s baris: " "%(line)s" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "Mode tidak sah %(mode)s di berkas: %(file)s baris: %(line)s" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" "Kesalahan Sintaksis: Entri jaringan yang tak diharapkan ditemukan pada " "berkas: %(file)s baris: %(line)s" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" "Kesalahan Sintaksis: Entri dbus yang tak diharapkan ditemukan pada berkas: " "%(file)s baris: %(line)s" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" "Kesalahan Sintaksis: Entry mount yang tak diharapkan ditemukan pada berkas: " "%(file)s baris: %(line)s" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" "Kesalahan Sintaksis: Entri signal yang tak diharapkan ditemukan pada berkas: " "%(file)s baris: %(line)s" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" "Kesalahan Sintaksis: Entri ptrace yang tak diharapkan ditemukan pada berkas: " "%(file)s baris: %(line)s" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" "Kesalahan Sintaksis: Entri pivot_root yang tak diharapkan ditemukan pada " "berkas: %(file)s baris: %(line)s" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" "Kesalahan Sintaksis: Entri unix yang tak diharapkan ditemukan pada berkas: " "%(file)s baris: %(line)s" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" "Kesalahan Sintaksis: Perubahan deklarasi topi yang tak diharapkan ditemukan " "pada berkas: %(file)s baris: %(line)s" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" "Kesalahan Sintaksis: Definisi topi yang tak diharapkan ditemukan pada " "berkas: %(file)s berkas: %(line)s" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "Kesalahan: Definisi ganda untuk topi %(hat)s di profil %(profile)s." #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "Peringatan: Baris \"REPOSITORY:\" tidak sah di %s, mengabaikan." #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "" "Kesalahan Sintaksis: Baris tak diketahui ditemukan pada berkas: %(file)s " "baris: %(line)s" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" "Kesalahan Sintaksis: Kehilangan '}' atau ','. Mencapai akhir berkas %(file)s " "ketika di dalam profil %(profile)s" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "" "Mendefinisikan kembali variabel %(variable)s yang telah ada: %(value)s di " "%(file)s" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" "Nilai ditambahkan ke variabel %(variable)s yang belum ada: %(value)s di " "%(file)s" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" "Operasi variabel %(operation)s tak diketahui untuk variabel %(variable)s di " "%(file)s" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "Mengizinkan string tidak sah: %(allow)s" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "Tak dapat menemukan profil yang telah ada untuk dimodifikasi" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "Menulis profil terbarui untuk %s." #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "Berkas Tidak Ditemukan: %s" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" "%s saat ini ditandai sebagai program yang seharusnya tidak memiliki profil " "sendiri.\n" "Biasanya, program ditandai seperti ini jika membuat sebuah profil untuknya \n" "sangat mungkin akan merusak sistem keseluruhan. Jika Anda tahu apa yang " "Anda lakukan\n" "dan yakin akan membuat sebuah profil untuk program ini, sunting entri\n" "yang terkait pada seksi [qualifiers] di /etc/apparmor/logprof.conf." #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "Log berisi mode tak diketahui %s" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" "Tidak dapat menemukan %(program)s di dalam daftar jalur sistem. Jika nama " "aplikasi\n" "benar, silakan jalankan 'which %(program)s' sebagai pengguna dengan " "lingkungan jalur\n" "ditentukan dengan benar untuk menemukan jalur terkualifikasi penuh dan\n" "gunakan jalur penuh sebagai parameter." #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "%s tidak ada, silakan periksa ulang jalurnya." #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" "Program yang dimaksud tidak ditemukan, silakan coba dengan nama jalur dari " "program yang terkualifikasi penuh: " #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "Profil untuk %s tidak ditemukan, melewati" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "Menonaktifkan %s." #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "Mengatur %s ke mode audit." #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "Menghapus mode audit dari %s." #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" "Silakan tentukan aplikasi untuk menghasilkan sebuah profil, bukan profil itu " "sendiri - melewati %s." #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "Profil untuk %s telah ada - melewati." #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" "\n" "Menghapus aturan %s." #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" "Profil lokal untuk %(program)s pada berkas %(file)s telah diubah. Apakah " "Anda ingin menyimpannya?" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "Profil untuk %s tidak ada. Tak ada yang dibersihkan." #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "Hotkey tidak sah untuk" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "(Y)a" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "(T)idak" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "(B)atal" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "(I)zinkan" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "(L)ebih" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "Audi(t)" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "Audi(t) nonaktif" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "Audit (S)emua" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "I(z)in pemilik aktif" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "I(z)in pemilik nonaktif" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "T(o)lak" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "Tin(g)galkan" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "S(e)lesai" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "(I)nherit" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "(P)rofil" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "(P)rofile Clean Exec" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "(C)hild" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "(C)hild Clean Exec" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "(N)amed" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "(N)amed Clean Exec" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "(U)nconfined" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "(U)nconfined Clean Exec" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "(P)rofile Inherit" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "(P)rofile Inherit Clean Exec" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "(C)hild Inherit" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "(C)hild Inherit Clean Exec" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "(N)amed Inherit" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "(N)amed Inherit Clean Exec" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "(X) Aktif" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "(X) Nonaktif" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "(S)impan Perubahan" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "(L)anjutkan Pemrofilan" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "(B)aru" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "(G)umpal" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "Gumpal dengan (E)kstensi" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "(T)ambahkan Topi yang Diminta" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "(G)unakan Topi Default" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "(P)indai log sistem untuk event AppArmor" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "(B)antuan" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "(L)ihat Profil" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "(G)unakan Profil" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "(B)uat Profil Baru" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "(P)erbarui Profil" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "(A)baikan Pembaruan" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "Simpan Profil (T)erpilih" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "(U)nggah Perubahan" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "(L)ihat Perubahan" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "Lihat Perubahan antara profil-profil (C)lean" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "(L)ihat" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "(A)ktifkan Repository" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "(N)onaktifkan Repository" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "(J)angan Tanya Lagi" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "(T)anya Saya Nanti" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "(I)zinkan Semua Jaringan" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "Izinkan (K)eluarga Jaringan" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "(T)impa Profil" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "(J)aga Profil" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "(L)anjut" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "(A)baikan" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "PromptUser: Perintah tak diketahui %s" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "PromptUser: Hotkey duplikat untuk %(command)s: %(menutext)s " #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "PromptUser: Hotkey tidak sah pada item default" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "PromptUser: Default tidak sah %s" apparmor-2.13.3/utils/po/hi.po0000644000175000017500000006103513502024172013730 0ustar jjjj# Hindi translation for apparmor # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: apparmor-utils\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2013-12-07 11:01+0000\n" "Last-Translator: Kshitij Gupta \n" "Language-Team: Hindi \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: hi\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "" #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "" #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "" #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" #: ../aa-genprof:147 msgid "Profiling" msgstr "प्रोफाइलिंग" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "%s के लिए प्रोफाइल उत्‍पन्‍न करना पूर्ण हुआ।" #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "" #: ../aa-mergeprof:31 msgid "your profile" msgstr "" #: ../aa-mergeprof:32 msgid "base profile" msgstr "" #: ../aa-mergeprof:33 msgid "other profile" msgstr "" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "पथ" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "" #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "पुरानी मेल खाने वाली %s प्रोफाइल प्रविष्टियों को हटाया गया।" #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "प्रोफाइल" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "क्षमता" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "गंभीरता" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "" #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "प्रोफाइल के लिए %s क्षमता जोड़ी जा रही है।" #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "प्रोफाइल के लिए %s क्षमता से इंकार किया जा रहा है।" #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "पुराना मोड" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "नया मोड" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "मोड" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "नया पथ प्रविष्‍ट करें: " #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "नेटवर्क फॅमिली" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "सॉकेट प्रकार" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "" #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "" #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "" #: ../aa-audit:26 msgid "remove audit mode" msgstr "" #: ../aa-audit:28 msgid "Show full trace" msgstr "" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "" #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "" #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "" #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "" #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "" #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "" #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "" #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "" #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "" #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "" #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "" #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "" #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "" #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "" #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "" #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "" #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "" #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "" #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "" #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "" #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "" #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "" #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "" #, python-format #~ msgid "Adding network access %s %s to profile." #~ msgstr "प्रोफाइल में %s %s नेटवर्क के उपयोग को जोड़ा जा रहा है।" apparmor-2.13.3/utils/po/README0000644000175000017500000000060413502024172013643 0ustar jjjjGENERATING TRANSLATION MESSAGES To generate the messages.pot file: Run the following command in Translate. python pygettext.py ../apparmor/*.py ../Tools/aa* It will generate the messages.pot file in the Translate directory. You might need to provide the full path to pygettext.py from your python installation. It will typically be in the /path/to/python/libs/Tools/i18n/pygettext.py apparmor-2.13.3/utils/po/pl.po0000644000175000017500000006003013502024172013735 0ustar jjjj# Polish translation for apparmor # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: apparmor\n" "Report-Msgid-Bugs-To: AppArmor list \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2015-01-20 09:38+0000\n" "Last-Translator: Rafal Kruk \n" "Language-Team: Polish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: pl\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "Wygeneruj profil dla danego programu" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "ścieżka do profili" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "ścieżka do pliku log" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "" #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" "Wyglada na to, że AppArmor nie został uruchomiony. Proszę uruchom AppArmor i " "spróbuj ponownie." #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "%s nie jest katalogiem." #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "" #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" "\n" "Zanim rozpoczniesz, może zechcesz sprawdzić czy istnieje profil dla " "aplikacji, która chcesz ograniczyć. Aby uzyskać więcej informacji, zobacz " "stronę wiki" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" #: ../aa-genprof:147 msgid "Profiling" msgstr "Profilowanie" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "Zokończono generowanie profilu dla %s." #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "" #: ../aa-mergeprof:31 msgid "your profile" msgstr "" #: ../aa-mergeprof:32 msgid "base profile" msgstr "" #: ../aa-mergeprof:33 msgid "other profile" msgstr "" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "Zaznacz te, które chcesz dodać" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "" #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "nieznany" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "" #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "Profil" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "Możliwość" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "Ważność" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "" #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "" #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "" #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "" #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "" #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "" #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "" #: ../aa-audit:26 msgid "remove audit mode" msgstr "" #: ../aa-audit:28 msgid "Show full trace" msgstr "" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "" #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "" #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "" #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "" #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "" #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "" #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "" #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "" #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "" #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "" #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "" #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "" #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "" #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "" #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "" #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "" #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "" #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "" #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "" #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "" #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "" #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "" #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "" apparmor-2.13.3/utils/po/Makefile0000644000175000017500000000205513502024172014425 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (c) 2004, 2005 NOVELL (All rights reserved) # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Novell, Inc. # ---------------------------------------------------------------------- all: # As translations get added, they will automatically be included, unless # the lang is explicitly added to DISABLED_LANGS; e.g. DISABLED_LANGS=en es DISABLED_LANGS= COMMONDIR=../../common include $(COMMONDIR)/Make-po.rules XGETTEXT_ARGS+=--language=perl --language=python apparmor-2.13.3/utils/po/uk.po0000644000175000017500000005707113502024172013754 0ustar jjjj# Ukrainian translation for apparmor # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: apparmor-utils\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2013-11-15 06:49+0000\n" "Last-Translator: AppArmor list \n" "Language-Team: Ukrainian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: uk\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "" #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "" #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "" #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" #: ../aa-genprof:147 msgid "Profiling" msgstr "" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "" #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "" #: ../aa-mergeprof:31 msgid "your profile" msgstr "" #: ../aa-mergeprof:32 msgid "base profile" msgstr "" #: ../aa-mergeprof:33 msgid "other profile" msgstr "" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "" #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "" #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "" #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "" #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "" #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "" #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "" #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "" #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "" #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "" #: ../aa-audit:26 msgid "remove audit mode" msgstr "" #: ../aa-audit:28 msgid "Show full trace" msgstr "" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "" #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "" #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "" #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "" #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "" #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "" #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "" #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "" #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "" #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "" #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "" #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "" #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "" #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "" #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "" #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "" #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "" #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "" #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "" #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "" #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "" #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "" #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "" apparmor-2.13.3/utils/po/de.po0000644000175000017500000010647313502024172013726 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # Copyright (C) 2013 Christian Boltz # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-utils\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-14 19:29+0530\n" "PO-Revision-Date: 2019-04-17 23:42+0000\n" "Last-Translator: Tobias Bannert \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-19 05:30+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: de\n" #: ../aa-genprof:56 msgid "Generate profile for the given program" msgstr "Profil für das angegebene Programm erstellen" #: ../aa-genprof:57 ../aa-logprof:25 ../aa-cleanprof:24 ../aa-mergeprof:34 #: ../aa-autodep:25 ../aa-audit:25 ../aa-complain:24 ../aa-enforce:24 #: ../aa-disable:24 msgid "path to profiles" msgstr "Pfad zu den Profilen" #: ../aa-genprof:58 ../aa-logprof:26 msgid "path to logfile" msgstr "Pfad zur Protokolldatei" #: ../aa-genprof:59 msgid "name of program to profile" msgstr "Name des Programms, für das ein Profil erstellt werden soll" #: ../aa-genprof:69 ../aa-logprof:37 #, python-format msgid "The logfile %s does not exist. Please check the path" msgstr "" "Die Protokolldatei %s ist nicht vorhanden. Bitte überprüfen Sie den Pfad." #: ../aa-genprof:75 ../aa-logprof:43 ../aa-unconfined:36 msgid "" "It seems AppArmor was not started. Please enable AppArmor and try again." msgstr "" "AppArmor wurde offenbar nicht gestartet. Aktivieren Sie AppArmor und " "versuchen Sie es erneut." #: ../aa-genprof:80 ../aa-mergeprof:47 #, python-format msgid "%s is not a directory." msgstr "%s ist kein Verzeichnis." #: ../aa-genprof:94 #, python-format msgid "" "Can't find %(profiling)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(profiling)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" "%(profiling)s kann nicht in der Systempfadliste gefunden werden. Wenn der\n" "Name der Anwendung richtig ist, bitte »which %(profiling)s« starten, als " "ein\n" "Benutzer mit der richtigem Pfadumgebung, um den vollständig qualifizierten\n" "Pfad zu finden und bitte den vollständigen Pfad als Parameter benutzen." #: ../aa-genprof:96 #, python-format msgid "%s does not exists, please double-check the path." msgstr "%s ist nicht vorhanden. Bitte überprüfen Sie den Pfad." #: ../aa-genprof:124 msgid "" "\n" "Before you begin, you may wish to check if a\n" "profile already exists for the application you\n" "wish to confine. See the following wiki page for\n" "more information:" msgstr "" "\n" "Bevor Sie beginnen, möchten Sie vielleicht prüfen,\n" "ob bereits ein Profil für das Programm besteht,\n" "das Sie einschränken möchten. Weitere Informationen\n" "können Sie auf der folgenden Wiki-Seite erhalten:" #: ../aa-genprof:126 msgid "" "Please start the application to be profiled in\n" "another window and exercise its functionality now.\n" "\n" "Once completed, select the \"Scan\" option below in \n" "order to scan the system logs for AppArmor events. \n" "\n" "For each AppArmor event, you will be given the \n" "opportunity to choose whether the access should be \n" "allowed or denied." msgstr "" "Starten Sie die Anwendung, für die ein Profil erstellt werden soll, in\n" "einem anderen Fenster, und führen Sie die Funktionalität jetzt aus.\n" "\n" "Nach Abschluss dieses Vorgangs bitte unten »Durchsuchen« wählen,\n" "um in den Systemprotokollen nach AppArmor-Ereignissen zu suchen. \n" "\n" "Für jedes AppArmor-Ereignis haben Sie die Gelegenheit anzugeben,\n" "ob der Zugriff zugelassen oder verweigert werden soll." #: ../aa-genprof:147 msgid "Profiling" msgstr "Profilerstellung" #: ../aa-genprof:165 msgid "" "\n" "Reloaded AppArmor profiles in enforce mode." msgstr "" "\n" "AppArmor-Profile wurden im Erzwingenmodus neu geladen." #: ../aa-genprof:166 msgid "" "\n" "Please consider contributing your new profile!\n" "See the following wiki page for more information:" msgstr "" "\n" "Bitte überlegen Sie es Ihr neues Profil beizusteuern.\n" "Weitere Informationen können Sie auf der folgenden Wiki-Seite erhalten:" #: ../aa-genprof:167 #, python-format msgid "Finished generating profile for %s." msgstr "Profilerstellung für %s abgeschlossen." #: ../aa-logprof:24 msgid "Process log entries to generate profiles" msgstr "Protokolleinträge verarbeiten, um Profile zu erstellen" #: ../aa-logprof:27 msgid "mark in the log to start processing after" msgstr "Verarbeitung ab dieser Markierung in der Protokolldatei starten" #: ../aa-cleanprof:23 msgid "Cleanup the profiles for the given programs" msgstr "Profile der genannten Programme werden bereinigt" #: ../aa-cleanprof:25 ../aa-autodep:26 ../aa-audit:27 ../aa-complain:25 #: ../aa-enforce:25 ../aa-disable:25 msgid "name of program" msgstr "Name des Programms" #: ../aa-cleanprof:26 msgid "Silently overwrite with a clean profile" msgstr "Kommentarloses Überschreiben mit einem sauberen Profil" #: ../aa-mergeprof:29 msgid "Perform a 2-way or 3-way merge on the given profiles" msgstr "" "Eine 2- oder 3-Wege-Zusammenführung auf den angegebenen Profilen durchführen" #: ../aa-mergeprof:31 msgid "your profile" msgstr "Ihr Profil" #: ../aa-mergeprof:32 msgid "base profile" msgstr "Grundprofil" #: ../aa-mergeprof:33 msgid "other profile" msgstr "anderes Profil" #: ../aa-mergeprof:67 ../apparmor/aa.py:2345 msgid "" "The following local profiles were changed. Would you like to save them?" msgstr "" "Die folgenden lokalen Profile wurden geändert. Möchten Sie sie speichern?" #: ../aa-mergeprof:148 ../aa-mergeprof:430 ../apparmor/aa.py:1767 msgid "Path" msgstr "Pfad" #: ../aa-mergeprof:149 msgid "Select the appropriate mode" msgstr "Wählen Sie den passenden Modus" #: ../aa-mergeprof:166 msgid "Unknown selection" msgstr "Unbekannte Auswahl" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "File includes" msgstr "Datei beinhaltet" #: ../aa-mergeprof:183 ../aa-mergeprof:209 msgid "Select the ones you wish to add" msgstr "Wählen Sie welche Sie hinzufügen möchten" #: ../aa-mergeprof:195 ../aa-mergeprof:222 #, python-format msgid "Adding %s to the file." msgstr "%s wird zum Profil hinzugefügt." #: ../aa-mergeprof:199 ../apparmor/aa.py:2258 msgid "unknown" msgstr "unbekannt" #: ../aa-mergeprof:224 ../aa-mergeprof:275 ../aa-mergeprof:516 #: ../aa-mergeprof:558 ../aa-mergeprof:675 ../apparmor/aa.py:1620 #: ../apparmor/aa.py:1859 ../apparmor/aa.py:1899 ../apparmor/aa.py:2012 #, python-format msgid "Deleted %s previous matching profile entries." msgstr "%s vorherige übereinstimmende Profileinträge wurden gelöscht." #: ../aa-mergeprof:244 ../aa-mergeprof:429 ../aa-mergeprof:629 #: ../aa-mergeprof:656 ../apparmor/aa.py:992 ../apparmor/aa.py:1252 #: ../apparmor/aa.py:1562 ../apparmor/aa.py:1603 ../apparmor/aa.py:1766 #: ../apparmor/aa.py:1958 ../apparmor/aa.py:1994 msgid "Profile" msgstr "Profil" #: ../aa-mergeprof:245 ../apparmor/aa.py:1563 ../apparmor/aa.py:1604 msgid "Capability" msgstr "Fähigkeit" #: ../aa-mergeprof:246 ../aa-mergeprof:480 ../apparmor/aa.py:1258 #: ../apparmor/aa.py:1564 ../apparmor/aa.py:1605 ../apparmor/aa.py:1817 msgid "Severity" msgstr "Schweregrad" #: ../aa-mergeprof:273 ../aa-mergeprof:514 ../apparmor/aa.py:1618 #: ../apparmor/aa.py:1857 #, python-format msgid "Adding %s to profile." msgstr "%s wird zum Profil hinzugefügt." #: ../aa-mergeprof:282 ../apparmor/aa.py:1627 #, python-format msgid "Adding capability %s to profile." msgstr "Fähigkeit %s wird zum Profil hinzugefügt." #: ../aa-mergeprof:289 ../apparmor/aa.py:1634 #, python-format msgid "Denying capability %s to profile." msgstr "Fähigkeit %s wird dem Profil verweigert." #: ../aa-mergeprof:439 ../aa-mergeprof:470 ../apparmor/aa.py:1776 #: ../apparmor/aa.py:1807 msgid "(owner permissions off)" msgstr "(Eigentümerberechtigungen deaktiviert)" #: ../aa-mergeprof:444 ../apparmor/aa.py:1781 msgid "(force new perms to owner)" msgstr "(neue Berechtigungen für Eigentümer erzwingen)" #: ../aa-mergeprof:447 ../apparmor/aa.py:1784 msgid "(force all rule perms to owner)" msgstr "(alle Regelberechtigungen für Eigentümer erzwingen)" #: ../aa-mergeprof:459 ../apparmor/aa.py:1796 msgid "Old Mode" msgstr "Alter Modus" #: ../aa-mergeprof:460 ../apparmor/aa.py:1797 msgid "New Mode" msgstr "Neuer Modus" #: ../aa-mergeprof:475 ../apparmor/aa.py:1812 msgid "(force perms to owner)" msgstr "(Berechtigungen für Eigentümer erzwingen)" #: ../aa-mergeprof:478 ../apparmor/aa.py:1815 msgid "Mode" msgstr "Modus" #: ../aa-mergeprof:556 #, python-format msgid "Adding %(path)s %(mod)s to profile" msgstr "%(path)s %(mod)s wird zum Profil hinzugefügt" #: ../aa-mergeprof:574 ../apparmor/aa.py:1915 msgid "Enter new path: " msgstr "Neuen Pfad eingeben: " #: ../aa-mergeprof:630 ../aa-mergeprof:657 ../apparmor/aa.py:1959 #: ../apparmor/aa.py:1995 msgid "Network Family" msgstr "Netzwerkfamilie" #: ../aa-mergeprof:631 ../aa-mergeprof:658 ../apparmor/aa.py:1960 #: ../apparmor/aa.py:1996 msgid "Socket Type" msgstr "Socket-Typ" #: ../aa-mergeprof:673 ../apparmor/aa.py:2010 #, python-format msgid "Adding %s to profile" msgstr "%s wird zum Profil hinzugefügt." #: ../aa-mergeprof:683 ../apparmor/aa.py:2020 #, python-format msgid "Adding network access %(family)s %(type)s to profile." msgstr "Netzwerkzugriff %(family)s %(type)s wird zum Profil hinzugefügt." #: ../aa-mergeprof:689 ../apparmor/aa.py:2026 #, python-format msgid "Denying network access %(family)s %(type)s to profile" msgstr "Netzwerkzugriff %(family)s %(type)s wird dem Profil verweigert." #: ../aa-autodep:23 msgid "Generate a basic AppArmor profile by guessing requirements" msgstr "Ein Basis-AppArmor-Profil nach erwarteten Anforderungen erstellen" #: ../aa-autodep:24 msgid "overwrite existing profile" msgstr "vorhandenes Profil überschreiben" #: ../aa-audit:24 msgid "Switch the given programs to audit mode" msgstr "Das angegebene Programm in den Prüfmodus versetzen" #: ../aa-audit:26 msgid "remove audit mode" msgstr "Prüfmodus entfernen" #: ../aa-audit:28 msgid "Show full trace" msgstr "Die vollständige Spur anzeigen" #: ../aa-complain:23 msgid "Switch the given program to complain mode" msgstr "Das angegebene Programm in den Complain-Modus versetzen" #: ../aa-enforce:23 msgid "Switch the given program to enforce mode" msgstr "Das angegebene Programm in den Erzwingenmodus versetzen" #: ../aa-disable:23 msgid "Disable the profile for the given programs" msgstr "Das Profil für die angegebenen Programme deaktivieren" #: ../aa-unconfined:28 msgid "Lists unconfined processes having tcp or udp ports" msgstr "Zeigt uneingeschränkte Prozesse mit tcp oder udp Ports" #: ../aa-unconfined:29 msgid "scan all processes from /proc" msgstr "alle Prozesse aus /proc durchsuchen" #: ../aa-unconfined:81 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) not confined" msgstr "%(pid)s %(program)s (%(commandline)s) nicht eingeschränkt" #: ../aa-unconfined:85 #, python-format msgid "%(pid)s %(program)s%(pname)s not confined" msgstr "%(pid)s %(program)s%(pname)s nicht eingeschränkt" #: ../aa-unconfined:90 #, python-format msgid "%(pid)s %(program)s (%(commandline)s) confined by '%(attribute)s'" msgstr "" "%(pid)s %(program)s (%(commandline)s) eingeschränkt durch '%(attribute)s'" #: ../aa-unconfined:94 #, python-format msgid "%(pid)s %(program)s%(pname)s confined by '%(attribute)s'" msgstr "%(pid)s %(program)s%(pname)s eingeschränkt durch '%(attribute)s'" #: ../apparmor/aa.py:196 #, python-format msgid "Followed too many links while resolving %s" msgstr "Zu vielen Verweisen beim Auflösen von %s gefolgt" #: ../apparmor/aa.py:252 ../apparmor/aa.py:259 #, python-format msgid "Can't find %s" msgstr "%s kann nicht gefunden werden" #: ../apparmor/aa.py:264 ../apparmor/aa.py:548 #, python-format msgid "Setting %s to complain mode." msgstr "%s wird in den Complain-Modus versetzt." #: ../apparmor/aa.py:271 #, python-format msgid "Setting %s to enforce mode." msgstr "%s wird in den Erzwingen-Modus versetzt." #: ../apparmor/aa.py:286 #, python-format msgid "Unable to find basename for %s." msgstr "Basisname für %s kann nicht gefunden werden." #: ../apparmor/aa.py:301 #, python-format msgid "Could not create %(link)s symlink to %(filename)s." msgstr "" "Symbolischer Link %(link)s zu %(filename)s kann nicht erstellt werden." #: ../apparmor/aa.py:314 #, python-format msgid "Unable to read first line from %s: File Not Found" msgstr "Kann die erste Zeile von %s nicht lesen: Datei nicht gefunden" #: ../apparmor/aa.py:328 #, python-format msgid "" "Unable to fork: %(program)s\n" "\t%(error)s" msgstr "" "Außerstande abzuzweigen: %(program)s\n" "\t%(error)s" #: ../apparmor/aa.py:449 ../apparmor/ui.py:303 msgid "" "Are you sure you want to abandon this set of profile changes and exit?" msgstr "Sind Sie sicher, dass Sie diese Profiländerungen verwerfen wollen?" #: ../apparmor/aa.py:451 ../apparmor/ui.py:305 msgid "Abandoning all changes." msgstr "Alle Änderungen verworfen." #: ../apparmor/aa.py:464 msgid "Connecting to repository..." msgstr "Zur Quelle wird verbunden …" #: ../apparmor/aa.py:470 msgid "WARNING: Error fetching profiles from the repository" msgstr "ACHTUNG: Fehler beim Abrufen der Profile von der Quelle" #: ../apparmor/aa.py:550 #, python-format msgid "Error activating profiles: %s" msgstr "Fehler beim Aktivieren des Profils: %s" #: ../apparmor/aa.py:605 #, python-format msgid "%s contains no profile" msgstr "%s enthält kein Profil" #: ../apparmor/aa.py:706 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository:\n" "%s\n" msgstr "" "ACHTUNG: Fehler beim Synchronisieren der Profile mit der Quelle:\n" "%s\n" #: ../apparmor/aa.py:744 #, python-format msgid "" "WARNING: Error synchronizing profiles with the repository\n" "%s" msgstr "" "ACHTUNG: Fehler beim Synchronisieren der Profile mit der Quelle:\n" "%s" #: ../apparmor/aa.py:832 ../apparmor/aa.py:883 #, python-format msgid "" "WARNING: An error occurred while uploading the profile %(profile)s\n" "%(ret)s" msgstr "" "ACHTUNG: beim Hochladen des Profils %(profile)s ist ein Fehler aufgetreten\n" "%(ret)s" #: ../apparmor/aa.py:833 msgid "Uploaded changes to repository." msgstr "Änderungen wurden zur Quelle hochgeladen." #: ../apparmor/aa.py:865 msgid "Changelog Entry: " msgstr "Änderungsprotokolleintrag: " #: ../apparmor/aa.py:885 msgid "" "Repository Error\n" "Registration or Signin was unsuccessful. User login\n" "information is required to upload profiles to the repository.\n" "These changes could not be sent." msgstr "" "Quellfehler\n" "Registrieren oder Anmelden ist fehlgeschlagen.\n" "Benutzerzugangsdaten sind erforderlich,\n" "um die Profile in die Quelle zu übertragen.\n" "Diese Änderungen konnten nicht übertragen werden." #: ../apparmor/aa.py:995 msgid "Default Hat" msgstr "Standard-Hat" #: ../apparmor/aa.py:997 msgid "Requested Hat" msgstr "Angeforderter Hat" #: ../apparmor/aa.py:1218 #, python-format msgid "%s has transition name but not transition mode" msgstr "%s hat einen Übergangsnamen aber keinen Übergangsmodus" #: ../apparmor/aa.py:1232 #, python-format msgid "Target profile exists: %s\n" msgstr "Zielprofil ist vorhanden: %s\n" #: ../apparmor/aa.py:1254 msgid "Program" msgstr "Programm" #: ../apparmor/aa.py:1257 msgid "Execute" msgstr "Ausführen" #: ../apparmor/aa.py:1287 msgid "Are you specifying a transition to a local profile?" msgstr "Sind Sie dabei einen Übergang zu einem lokalen Profil festzulegen?" #: ../apparmor/aa.py:1299 msgid "Enter profile name to transition to: " msgstr "Bitte den Ziel-Profilnamen eingeben: " #: ../apparmor/aa.py:1308 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but some applications depend on the presence\n" "of LD_PRELOAD or LD_LIBRARY_PATH." msgstr "" "Soll AppArmor die Umgebung bereinigen wenn\n" "Profile gewechselt werden?\n" "\n" "Ein bereinigen der Umgebung ist sicherer,\n" "aber manche Anwendungen sind abhängig\n" "von LD_PRELOAD oder LD_LIBRARY_PATH." #: ../apparmor/aa.py:1310 msgid "" "Should AppArmor sanitise the environment when\n" "switching profiles?\n" "\n" "Sanitising environment is more secure,\n" "but this application appears to be using LD_PRELOAD\n" "or LD_LIBRARY_PATH and sanitising the environment\n" "could cause functionality problems." msgstr "" "Soll AppArmor die Umgebung bereinigen wenn\n" "Profile gewechselt werden?\n" "\n" "Ein bereinigen der Umgebung ist sicherer,\n" "aber diese Anwendung scheint LD_PRELOAD\n" "oder LD_LIBRARY-PATH zu nutzen und ein bereinigen der Umgebung\n" "könnte die Funktionsfähigkeit beeinträchtigen." #: ../apparmor/aa.py:1318 #, python-format msgid "" "Launching processes in an unconfined state is a very\n" "dangerous operation and can cause serious security holes.\n" "\n" "Are you absolutely certain you wish to remove all\n" "AppArmor protection when executing %s ?" msgstr "" "Das Starten von Prozessen mit uneingeschränktem Status ist sehr\n" "gefährlich und kann ernsthafte Sicherheitslöcher verursachen.\n" "\n" "Sind sie sich absolut sicher, dass Sie sämtlichen Schutz durch\n" "AppArmor entfernen wollen, wenn sie %s ausführen ?" #: ../apparmor/aa.py:1320 msgid "" "Should AppArmor sanitise the environment when\n" "running this program unconfined?\n" "\n" "Not sanitising the environment when unconfining\n" "a program opens up significant security holes\n" "and should be avoided if at all possible." msgstr "" "Soll AppArmor die Umgebung bereinigen wenn\n" "dieses Programm uneingeschränkt ausgeführt wird?\n" "\n" "Ein nicht bereinigen der Umgebung öffnet bei uneingeschränkten\n" "Programmen siginifikante Sicherheitslöcher\n" "und sollte wenn möglich vermieden werden." #: ../apparmor/aa.py:1396 ../apparmor/aa.py:1414 #, python-format msgid "" "A profile for %s does not exist.\n" "Do you want to create one?" msgstr "" "Für %s existiert kein Profil.\n" "Möchten Sie eins erstellen?" #: ../apparmor/aa.py:1523 msgid "Complain-mode changes:" msgstr "Änderungen im complain-Modus" #: ../apparmor/aa.py:1525 msgid "Enforce-mode changes:" msgstr "Änderungen im Erzwingen-Modus" #: ../apparmor/aa.py:1528 #, python-format msgid "Invalid mode found: %s" msgstr "Ungültiger Modus gefunden: %s" #: ../apparmor/aa.py:1897 #, python-format msgid "Adding %(path)s %(mode)s to profile" msgstr "Füge %(path)s %(mode)s zum Profil hinzu" #: ../apparmor/aa.py:1918 #, python-format msgid "" "The specified path does not match this log entry:\n" "\n" " Log Entry: %(path)s\n" " Entered Path: %(ans)s\n" "Do you really want to use this path?" msgstr "" "Der festgelegt Pfad passt nicht zu diesem Protokolleintrag:\n" "\n" " Protokolleintrag: %(path)s\n" " Eingegebener Pfad: %(ans)s\n" "Wollen Sie wirklich diesen Pfad benutzen?" #: ../apparmor/aa.py:2251 #, python-format msgid "Reading log entries from %s." msgstr "Protokolleinträge von %s werden gelesen." #: ../apparmor/aa.py:2254 #, python-format msgid "Updating AppArmor profiles in %s." msgstr "AppArmor-Profile in %s werden aktualisiert." #: ../apparmor/aa.py:2323 msgid "" "Select which profile changes you would like to save to the\n" "local profile set." msgstr "" "Wählen Sie welche Profiländerungen Sie in den lokalen\n" "Profilen speichern möchten." #: ../apparmor/aa.py:2324 msgid "Local profile changes" msgstr "Lokale Profiländerungen" #: ../apparmor/aa.py:2418 msgid "Profile Changes" msgstr "Profiländerungen" #: ../apparmor/aa.py:2428 #, python-format msgid "Can't find existing profile %s to compare changes." msgstr "" "Es kann kein vorhandenes Profil %s gefunden werden, um Änderungen zu " "vergleichen." #: ../apparmor/aa.py:2566 ../apparmor/aa.py:2581 #, python-format msgid "Can't read AppArmor profiles in %s" msgstr "AppArmor-Profile in %s können nicht gelesen werden" #: ../apparmor/aa.py:2677 #, python-format msgid "" "%(profile)s profile in %(file)s contains syntax errors in line: %(line)s." msgstr "" "Profil %(profile)s in %(file)s enthält Syntaxfehler in Zeile: %(line)s." #: ../apparmor/aa.py:2734 #, python-format msgid "" "Syntax Error: Unexpected End of Profile reached in file: %(file)s line: " "%(line)s" msgstr "" "Syntaxfehler: Unerwartetes Profilende erreicht in Datei: %(file)s Zeile: " "%(line)s" #: ../apparmor/aa.py:2749 #, python-format msgid "" "Syntax Error: Unexpected capability entry found in file: %(file)s line: " "%(line)s" msgstr "" "Syntaxfehler: Unerwarteter Fähigkeitseintrag gefunden in Datei: %(file)s " "Zeile: %(line)s" #: ../apparmor/aa.py:2770 #, python-format msgid "" "Syntax Error: Unexpected link entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfehler: Unerwarteter link-Eintrag gefunden in Datei: %(file)s Zeile: " "%(line)s" #: ../apparmor/aa.py:2798 #, python-format msgid "" "Syntax Error: Unexpected change profile entry found in file: %(file)s line: " "%(line)s" msgstr "" "Syntaxfehler: Unerwarteter change profile-Eintrag gefunden in Datei: " "%(file)s Zeile: %(line)s" #: ../apparmor/aa.py:2820 #, python-format msgid "" "Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfehler: Unerwarteter rlimit-Eintrag gefunden in Datei: %(file)s Zeile: " "%(line)s" #: ../apparmor/aa.py:2831 #, python-format msgid "" "Syntax Error: Unexpected boolean definition found in file: %(file)s line: " "%(line)s" msgstr "" "Syntaxfehler: Unerwarteter boolesche Variable gefunden in Datei: %(file)s " "Zeile: %(line)s" #: ../apparmor/aa.py:2871 #, python-format msgid "" "Syntax Error: Unexpected bare file rule found in file: %(file)s line: " "%(line)s" msgstr "" "Syntaxfehler: Unerwartete file-Regel gefunden in Datei: %(file)s Zeile: " "%(line)s" #: ../apparmor/aa.py:2894 #, python-format msgid "" "Syntax Error: Unexpected path entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfehler: Unerwarteter Pfad-Eintrag gefunden in Datei: %(file)s Zeile: " "%(line)s" #: ../apparmor/aa.py:2922 #, python-format msgid "Syntax Error: Invalid Regex %(path)s in file: %(file)s line: %(line)s" msgstr "" "Syntaxfehler: Ungültige Regex %(path)s in Datei: %(file)s Zeile: %(line)s" #: ../apparmor/aa.py:2925 #, python-format msgid "Invalid mode %(mode)s in file: %(file)s line: %(line)s" msgstr "Ungültiger Modus %(mode)s in Datei: %(file)s Zeile: %(line)s" #: ../apparmor/aa.py:2977 #, python-format msgid "" "Syntax Error: Unexpected network entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfehler: Unerwarteter network-Eintrag gefunden in Datei: %(file)s " "Zeile: %(line)s" #: ../apparmor/aa.py:3007 #, python-format msgid "" "Syntax Error: Unexpected dbus entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfehler: Unerwarteter dbus-Eintrag gefunden in Datei: %(file)s Zeile: " "%(line)s" #: ../apparmor/aa.py:3030 #, python-format msgid "" "Syntax Error: Unexpected mount entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfehler: Unerwarteter mount-Eintrag gefunden in Datei: %(file)s Zeile: " "%(line)s" #: ../apparmor/aa.py:3052 #, python-format msgid "" "Syntax Error: Unexpected signal entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfehler: Unerwarteter signal-Eintrag gefunden in Datei: %(file)s Zeile: " "%(line)s" #: ../apparmor/aa.py:3074 #, python-format msgid "" "Syntax Error: Unexpected ptrace entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfehler: Unerwarteter ptrace-Eintrag gefunden in Datei: %(file)s Zeile: " "%(line)s" #: ../apparmor/aa.py:3096 #, python-format msgid "" "Syntax Error: Unexpected pivot_root entry found in file: %(file)s line: " "%(line)s" msgstr "" "Syntaxfehler: Unerwarteter pivot_root-Eintrag gefunden in Datei: %(file)s " "Zeile: %(line)s" #: ../apparmor/aa.py:3118 #, python-format msgid "" "Syntax Error: Unexpected unix entry found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfehler: Unerwarteter unix-Eintrag gefunden in Datei: %(file)s Zeile: " "%(line)s" #: ../apparmor/aa.py:3140 #, python-format msgid "" "Syntax Error: Unexpected change hat declaration found in file: %(file)s " "line: %(line)s" msgstr "" "Syntaxfehler: Unerwartete change hat-Deklaration gefunden in Datei: %(file)s " "Zeile: %(line)s" #: ../apparmor/aa.py:3152 #, python-format msgid "" "Syntax Error: Unexpected hat definition found in file: %(file)s line: " "%(line)s" msgstr "" "Syntaxfehler: Unerwartete hat-Deklaration gefunden in Datei: %(file)s Zeile: " "%(line)s" #: ../apparmor/aa.py:3168 #, python-format msgid "Error: Multiple definitions for hat %(hat)s in profile %(profile)s." msgstr "Fehler: Mehrfache Definition für hat %(hat)s im Profil %(profile)s." #: ../apparmor/aa.py:3185 #, python-format msgid "Warning: invalid \"REPOSITORY:\" line in %s, ignoring." msgstr "ACHTUNG: ungültige Quellzeile »REPOSITORY:« in %s, wird übergangen." #: ../apparmor/aa.py:3198 #, python-format msgid "Syntax Error: Unknown line found in file: %(file)s line: %(line)s" msgstr "" "Syntaxfehler: Unbekannte Zeile gefunden in Datei: %(file)s Zeile: %(line)s" #: ../apparmor/aa.py:3211 #, python-format msgid "" "Syntax Error: Missing '}' or ','. Reached end of file %(file)s while inside " "profile %(profile)s" msgstr "" "Syntaxfehler: fehlende Zeichen »}« oder »,«. Dateiende von %(file)s " "innerhalb des Profils %(profile)s erreicht" #: ../apparmor/aa.py:3277 #, python-format msgid "Redefining existing variable %(variable)s: %(value)s in %(file)s" msgstr "" "Vorhandene Variable %(variable)s wird neu bestimmt: %(value)s in %(file)s" #: ../apparmor/aa.py:3282 #, python-format msgid "" "Values added to a non-existing variable %(variable)s: %(value)s in %(file)s" msgstr "" #: ../apparmor/aa.py:3284 #, python-format msgid "" "Unknown variable operation %(operation)s for variable %(variable)s in " "%(file)s" msgstr "" "Unbekannte Variablenoperation %(operation)s für Variable %(variable)s in " "%(file)s" #: ../apparmor/aa.py:3343 #, python-format msgid "Invalid allow string: %(allow)s" msgstr "" #: ../apparmor/aa.py:3778 msgid "Can't find existing profile to modify" msgstr "Vorhandenes Profil kann nicht zum Verändern gefunden werden" #: ../apparmor/aa.py:4347 #, python-format msgid "Writing updated profile for %s." msgstr "Aktualisiertes Profil für %s wird geschrieben." #: ../apparmor/aa.py:4481 #, python-format msgid "File Not Found: %s" msgstr "Datei nicht gefunden: %s" #: ../apparmor/aa.py:4591 #, python-format msgid "" "%s is currently marked as a program that should not have its own\n" "profile. Usually, programs are marked this way if creating a profile for \n" "them is likely to break the rest of the system. If you know what you're\n" "doing and are certain you want to create a profile for this program, edit\n" "the corresponding entry in the [qualifiers] section in " "/etc/apparmor/logprof.conf." msgstr "" "%s ist zurzeit markiert als ein Programm das nicht sein eigenes\n" "Profil haben sollte. Üblicherweise sind solche Programme so markiert da das " "erstellen eines Profils für \n" "sie den Rest des Systems zum Absturz bringen könnte. Wenn Sie wissen was " "Sie\n" "tun und sicher sind das Sie ein Profil für dieses Programm erstellen " "möchten, bearbeiten\n" "Sie den enstprechenden Eintrag im [qualifiers] Abschnitt in " "/etc/apparmor/logprof.conf." #: ../apparmor/logparser.py:127 ../apparmor/logparser.py:132 #, python-format msgid "Log contains unknown mode %s" msgstr "Protokolldatei enthält unbekannten Modus %s" #: ../apparmor/tools.py:84 ../apparmor/tools.py:126 #, python-format msgid "" "Can't find %(program)s in the system path list. If the name of the " "application\n" "is correct, please run 'which %(program)s' as a user with correct PATH\n" "environment set up in order to find the fully-qualified path and\n" "use the full path as parameter." msgstr "" #: ../apparmor/tools.py:86 ../apparmor/tools.py:102 ../apparmor/tools.py:128 #, python-format msgid "%s does not exist, please double-check the path." msgstr "%s existiert nicht, bitte überprüfen Sie den Pfad." #: ../apparmor/tools.py:100 msgid "" "The given program cannot be found, please try with the fully qualified path " "name of the program: " msgstr "" "Das angegebene Programm kann nicht gefunden werden, bitte geben Sie den " "vollständigen Pfad des Programms an: " #: ../apparmor/tools.py:113 ../apparmor/tools.py:137 ../apparmor/tools.py:157 #: ../apparmor/tools.py:175 ../apparmor/tools.py:193 #, python-format msgid "Profile for %s not found, skipping" msgstr "Profil für %s nicht gefunden, wird übersprungen" #: ../apparmor/tools.py:140 #, python-format msgid "Disabling %s." msgstr "%s wird deaktiviert." #: ../apparmor/tools.py:198 #, python-format msgid "Setting %s to audit mode." msgstr "%s wird in den Prüfmodus versetzt." #: ../apparmor/tools.py:200 #, python-format msgid "Removing audit mode from %s." msgstr "Prüfmodus wird von %s entfernt." #: ../apparmor/tools.py:212 #, python-format msgid "" "Please pass an application to generate a profile for, not a profile itself - " "skipping %s." msgstr "" #: ../apparmor/tools.py:220 #, python-format msgid "Profile for %s already exists - skipping." msgstr "Profil für %s besteht bereits - wird übersprungen." #: ../apparmor/tools.py:232 #, python-format msgid "" "\n" "Deleted %s rules." msgstr "" "\n" "%s Regeln gelöscht." #: ../apparmor/tools.py:240 #, python-format msgid "" "The local profile for %(program)s in file %(file)s was changed. Would you " "like to save it?" msgstr "" "Das lokale Profil für %(program)s in Datei %(file)s wurde geändert. Möchten " "Sie es speichern?" #: ../apparmor/tools.py:260 #, python-format msgid "The profile for %s does not exists. Nothing to clean." msgstr "Das Profil für %s existiert nicht. Nichts zu bereinigen." #: ../apparmor/ui.py:61 msgid "Invalid hotkey for" msgstr "Ungültiges Tastenkürzel für" #: ../apparmor/ui.py:77 ../apparmor/ui.py:121 ../apparmor/ui.py:275 msgid "(Y)es" msgstr "(J)a" #: ../apparmor/ui.py:78 ../apparmor/ui.py:122 ../apparmor/ui.py:276 msgid "(N)o" msgstr "(N)ein" #: ../apparmor/ui.py:123 msgid "(C)ancel" msgstr "(A)bbrechen" #: ../apparmor/ui.py:223 msgid "(A)llow" msgstr "Erl(a)uben" #: ../apparmor/ui.py:224 msgid "(M)ore" msgstr "(M)ehr" #: ../apparmor/ui.py:225 msgid "Audi(t)" msgstr "Audi(t)" #: ../apparmor/ui.py:226 msgid "Audi(t) off" msgstr "Audi(t) aus" #: ../apparmor/ui.py:227 msgid "Audit (A)ll" msgstr "(A)lle überprüfen" #: ../apparmor/ui.py:229 msgid "(O)wner permissions on" msgstr "Be(s)itzerberechtigungen an" #: ../apparmor/ui.py:230 msgid "(O)wner permissions off" msgstr "Be(s)itzerberechtigungen aus" #: ../apparmor/ui.py:231 msgid "(D)eny" msgstr "A(b)lehnen" #: ../apparmor/ui.py:232 msgid "Abo(r)t" msgstr "Abb(r)echen" #: ../apparmor/ui.py:233 msgid "(F)inish" msgstr "En(d)e" #: ../apparmor/ui.py:234 msgid "(I)nherit" msgstr "(E)rben" #: ../apparmor/ui.py:235 msgid "(P)rofile" msgstr "(P)rofil" #: ../apparmor/ui.py:236 msgid "(P)rofile Clean Exec" msgstr "" #: ../apparmor/ui.py:237 msgid "(C)hild" msgstr "(K)ind" #: ../apparmor/ui.py:238 msgid "(C)hild Clean Exec" msgstr "" #: ../apparmor/ui.py:239 msgid "(N)amed" msgstr "" #: ../apparmor/ui.py:240 msgid "(N)amed Clean Exec" msgstr "" #: ../apparmor/ui.py:241 msgid "(U)nconfined" msgstr "" #: ../apparmor/ui.py:242 msgid "(U)nconfined Clean Exec" msgstr "" #: ../apparmor/ui.py:243 msgid "(P)rofile Inherit" msgstr "(P)rofil erben" #: ../apparmor/ui.py:244 msgid "(P)rofile Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:245 msgid "(C)hild Inherit" msgstr "(K)ind erben" #: ../apparmor/ui.py:246 msgid "(C)hild Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:247 msgid "(N)amed Inherit" msgstr "" #: ../apparmor/ui.py:248 msgid "(N)amed Inherit Clean Exec" msgstr "" #: ../apparmor/ui.py:249 msgid "(X) ix On" msgstr "" #: ../apparmor/ui.py:250 msgid "(X) ix Off" msgstr "" #: ../apparmor/ui.py:251 ../apparmor/ui.py:265 msgid "(S)ave Changes" msgstr "Änderungen (s)peichern" #: ../apparmor/ui.py:252 msgid "(C)ontinue Profiling" msgstr "" #: ../apparmor/ui.py:253 msgid "(N)ew" msgstr "(N)eu" #: ../apparmor/ui.py:254 msgid "(G)lob" msgstr "" #: ../apparmor/ui.py:255 msgid "Glob with (E)xtension" msgstr "" #: ../apparmor/ui.py:256 msgid "(A)dd Requested Hat" msgstr "" #: ../apparmor/ui.py:257 msgid "(U)se Default Hat" msgstr "" #: ../apparmor/ui.py:258 msgid "(S)can system log for AppArmor events" msgstr "" #: ../apparmor/ui.py:259 msgid "(H)elp" msgstr "(H)ilfe" #: ../apparmor/ui.py:260 msgid "(V)iew Profile" msgstr "" #: ../apparmor/ui.py:261 msgid "(U)se Profile" msgstr "" #: ../apparmor/ui.py:262 msgid "(C)reate New Profile" msgstr "" #: ../apparmor/ui.py:263 msgid "(U)pdate Profile" msgstr "" #: ../apparmor/ui.py:264 msgid "(I)gnore Update" msgstr "" #: ../apparmor/ui.py:266 msgid "Save Selec(t)ed Profile" msgstr "Ausgewähl(t)es Profil speichern" #: ../apparmor/ui.py:267 msgid "(U)pload Changes" msgstr "" #: ../apparmor/ui.py:268 msgid "(V)iew Changes" msgstr "" #: ../apparmor/ui.py:269 msgid "View Changes b/w (C)lean profiles" msgstr "" #: ../apparmor/ui.py:270 msgid "(V)iew" msgstr "" #: ../apparmor/ui.py:271 msgid "(E)nable Repository" msgstr "Quelle (a)ktivieren" #: ../apparmor/ui.py:272 msgid "(D)isable Repository" msgstr "Quelle (d)eaktivieren" #: ../apparmor/ui.py:273 msgid "(N)ever Ask Again" msgstr "(N)icht mehr fragen" #: ../apparmor/ui.py:274 msgid "Ask Me (L)ater" msgstr "" #: ../apparmor/ui.py:277 msgid "Allow All (N)etwork" msgstr "" #: ../apparmor/ui.py:278 msgid "Allow Network Fa(m)ily" msgstr "" #: ../apparmor/ui.py:279 msgid "(O)verwrite Profile" msgstr "" #: ../apparmor/ui.py:280 msgid "(K)eep Profile" msgstr "" #: ../apparmor/ui.py:281 msgid "(C)ontinue" msgstr "" #: ../apparmor/ui.py:282 msgid "(I)gnore" msgstr "(I)gnorieren" #: ../apparmor/ui.py:344 #, python-format msgid "PromptUser: Unknown command %s" msgstr "PromptUser: Unbekannter Befehl %s" #: ../apparmor/ui.py:351 #, python-format msgid "PromptUser: Duplicate hotkey for %(command)s: %(menutext)s " msgstr "" #: ../apparmor/ui.py:363 msgid "PromptUser: Invalid hotkey in default item" msgstr "PromptUser: Ungültiges Tastenkürzel für den Standardwert" #: ../apparmor/ui.py:368 #, python-format msgid "PromptUser: Invalid default %s" msgstr "PromptUser: Ungültiger Standardwert %s" #, python-format #~ msgid "Adding network access %s %s to profile." #~ msgstr "Netzwerkzugriff '%s' '%s' wird zum Profil hinzugefügt." #, python-format #~ msgid "" #~ "Can't find %s in the system path list. If the name of the application\n" #~ "is correct, please run 'which %s' as a user with correct PATH\n" #~ "environment set up in order to find the fully-qualified path and\n" #~ "use the full path as parameter." #~ msgstr "" #~ "%s wurde in der Systempfadliste nicht gefunden. Wenn der Name der Anwendung\n" #~ "richtig ist, führen Sie 'which %s' als Benutzer mit korrekter PATH-Umgebung\n" #~ "aus, um den vollständig qualifizierten Pfad zu finden, und benutzen Sie " #~ "diesen\n" #~ "als Parameter." #, python-format #~ msgid "Adding %s %s to profile" #~ msgstr "%s %s wird zum Profil hinzugefügt." #, python-format #~ msgid "Denying network access %s %s to profile" #~ msgstr "Netzwerkzugriff '%s' '%s' wird dem Profil verweigert." #~ msgid "remove complain mode" #~ msgstr "Complain-Modus entfernen" #~ msgid "switch to complain mode" #~ msgstr "In den Complain-Modus versetzen" #, python-format #~ msgid "%s %s (%s) not confined\n" #~ msgstr "%s %s (%s) nicht eingeschränkt\n" #, python-format #~ msgid "%s %s %snot confined\n" #~ msgstr "%s %s %snicht eingeschränkt\n" #, python-format #~ msgid "%s %s %sconfined by '%s'\n" #~ msgstr "%s %s %seingeschränkt durch '%s'\n" apparmor-2.13.3/utils/aa-cleanprof.80000644000175000017500000001205613502024375014777 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "AA-CLEANPROF 8" .TH AA-CLEANPROF 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa\-cleanprof \- clean an existing AppArmor security profile. .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-cleanprof \f(BI\fB [\f(BI\fB ...] [\f(BI\-d /path/to/profiles\fB] [\f(BI\-\-no\-reload]\fB [\f(BI\-s\fB]\fR .SH "OPTIONS" .IX Header "OPTIONS" \&\fB\-d \-\-dir /path/to/profiles\fR .PP .Vb 2 \& Specifies where to look for the AppArmor security profile set. \& Defaults to /etc/apparmor.d. .Ve .PP \&\fB\-\-no\-reload\fR Do not reload the profile after modifying it. .PP \&\fB\-s \-\-silent\fR .PP .Vb 1 \& Silently overwrites the profile without user prompt. .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBaa-cleanprof\fR is used to perform a cleanup on one or more profiles. The tool removes any existing superfluous rules (rules that are covered under an include or another rule), reorders the rules to group similar rules together and removes all comments from the file. .SH "BUGS" .IX Header "BUGS" If you find any bugs, please report them at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7), \fIapparmor.d\fR\|(5), \fIaa\-enforce\fR\|(1), \fIaa\-complain\fR\|(1), \fIaa\-disable\fR\|(1), \&\fIaa_change_hat\fR\|(2), and . apparmor-2.13.3/utils/logprof.conf0000644000175000017500000001203013502024172014660 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2004-2006 Novell/SUSE # Copyright (C) 2014 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ [settings] profiledir = /etc/apparmor.d /etc/subdomain.d inactive_profiledir = /usr/share/apparmor/extra-profiles logfiles = /var/log/audit/audit.log /var/log/syslog /var/log/messages parser = /sbin/apparmor_parser /sbin/subdomain_parser ldd = /usr/bin/ldd logger = /bin/logger /usr/bin/logger # customize how file ownership permissions are presented # 0 - off # 1 - default of what ever mode the log reported # 2 - force the new permissions to be user # 3 - force all perms on the rule to be user default_owner_prompt = 1 # custom directory locations to look for #includes # # each name should be a valid directory containing possible #include # candidate files under the profile dir which by default is /etc/apparmor.d. # # So an entry of my-includes will allow /etc/apparmor.d/my-includes to # be used by the yast UI and profiling tools as a source of #include # files. custom_includes = [repository] distro = ubuntu-intrepid url = http://apparmor.test.opensuse.org/backend/api preferred_user = ubuntu [qualifiers] # things will be painfully broken if bash has a profile /bin/bash = icnu /usr/bin/bash = icnu /bin/ksh = icnu /usr/bin/ksh = icnu /bin/dash = icnu /usr/bin/dash = icnu /bin/zsh = icnu /usr/bin/zsh = icnu # these programs can't function if they're confined /bin/mount = u /usr/bin/mount = u /etc/init.d/subdomain = u /sbin/cardmgr = u /usr/sbin/cardmgr = u /sbin/subdomain_parser = u /usr/sbin/subdomain_parser = u /usr/sbin/genprof = u /usr/sbin/logprof = u /usr/lib/YaST2/servers_non_y2/ag_genprof = u /usr/lib/YaST2/servers_non_y2/ag_logprof = u # these ones shouln't have their own profiles /bin/awk = icn /usr/bin/awk = icn /bin/cat = icn /usr/bin/cat = icn /bin/chmod = icn /usr/bin/chmod = icn /bin/chown = icn /usr/bin/chown = icn /bin/cp = icn /usr/bin/cp = icn /bin/gawk = icn /usr/bin/gawk = icn /bin/grep = icn /usr/bin/grep = icn /bin/gunzip = icn /usr/bin/gunzip = icn /bin/gzip = icn /usr/bin/gzip = icn /bin/kill = icn /usr/bin/kill = icn /bin/ln = icn /usr/bin/ln = icn /bin/ls = icn /usr/bin/ls = icn /bin/mkdir = icn /usr/bin/mkdir = icn /bin/mv = icn /usr/bin/mv = icn /bin/readlink = icn /usr/bin/readlink = icn /bin/rm = icn /usr/bin/rm = icn /bin/sed = icn /usr/bin/sed = icn /bin/touch = icn /usr/bin/touch = icn /sbin/killall5 = icn /usr/sbin/killall5 = icn /usr/bin/find = icn /usr/bin/killall = icn /usr/bin/nice = icn /usr/bin/perl = icn /usr/bin/python = icn /usr/bin/python2 = icn /usr/bin/python2.7 = icn /usr/bin/python3 = icn /usr/bin/python3.3 = icn /usr/bin/python3.4 = icn /usr/bin/python3.5 = icn /usr/bin/python3.6 = icn /usr/bin/python3.7 = icn /usr/bin/tr = icn [required_hats] ^.+/apache(|2|2-prefork)$ = DEFAULT_URI HANDLING_UNTRUSTED_INPUT ^.+/httpd(|2|2-prefork)$ = DEFAULT_URI HANDLING_UNTRUSTED_INPUT [defaulthat] ^.+/apache(|2|2-prefork)$ = DEFAULT_URI ^.+/httpd(|2|2-prefork)$ = DEFAULT_URI [globs] # /foo/bar/lib/libbaz.so -> /foo/bar/lib/lib* /lib/lib[^\/]+so[^\/]*$ = /lib/lib*so* # strip kernel version numbers from kernel module accesses ^/lib/modules/[^\/]+\/ = /lib/modules/*/ # strip pid numbers from /proc accesses ^/proc/\d+/ = /proc/*/ # if it looks like a home directory, glob out the username ^/home/[^\/]+ = /home/* # if they use any perl modules, grant access to all ^/usr/lib/perl5/.+$ = /usr/lib/perl5/** ^/usr/lib/[^\/]+/perl5?/.+$ = /usr/lib/@{multiarch}/perl{,5}/** # locale foo ^/usr/lib/locale/.+$ = /usr/lib/locale/** ^/usr/share/locale/.+$ = /usr/share/locale/** # timezone fun ^/usr/share/zoneinfo/.+$ = /usr/share/zoneinfo/** # /foobar/fonts/baz -> /foobar/fonts/** /fonts/.+$ = /fonts/** # turn /foo/bar/baz.8907234 into /foo/bar/baz.* # BUGBUG - this one looked weird because it would suggest a glob for # BUGBUG - libfoo.so.5.6.0 that looks like libfoo.so.5.6.* # \.\d+$ = .* # some various /etc/security poo -- dunno about these ones... ^/etc/security/_[^\/]+$ = /etc/security/* ^/lib/security/pam_filter/[^\/]+$ = /lib/security/pam_filter/* ^/lib/security/pam_[^\/]+\.so$ = /lib/security/pam_*.so ^/etc/pam.d/[^\/]+$ = /etc/pam.d/* ^/etc/profile.d/[^\/]+\.sh$ = /etc/profile.d/*.sh apparmor-2.13.3/utils/aa-enforce0000755000175000017500000000261713502024172014301 0ustar jjjj#! /usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import argparse import apparmor.tools # setup exception handling from apparmor.fail import enable_aa_exception_handler enable_aa_exception_handler() # setup module translations from apparmor.translations import init_translation _ = init_translation() parser = argparse.ArgumentParser(description=_('Switch the given program to enforce mode')) parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) parser.add_argument('program', type=str, nargs='+', help=_('name of program')) parser.add_argument('--no-reload', dest='do_reload', action='store_false', default=True, help=_('Do not reload the profile after modifying it')) args = parser.parse_args() tool = apparmor.tools.aa_tools('enforce', args) tool.cmd_enforce() apparmor-2.13.3/utils/aa-remove-unknown0000644000175000017500000000577413502024172015656 0ustar jjjj#!/bin/sh # ---------------------------------------------------------------------- # Copyright (c) 2017 Canonical Ltd. (All rights reserved) # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # ---------------------------------------------------------------------- APPARMOR_FUNCTIONS=/lib/apparmor/rc.apparmor.functions APPARMORFS=/sys/kernel/security/apparmor PROFILES="${APPARMORFS}/profiles" REMOVE="${APPARMORFS}/.remove" DRY_RUN=0 . $APPARMOR_FUNCTIONS usage() { local progname="$1" local rc="$2" local msg="usage: ${progname} [options] Remove profiles unknown to the system Options: -h, --help Show this help message and exit -n Dry run; don't remove profiles" if [ "$rc" -ne 0 ] ; then echo "$msg" 1>&2 else echo "$msg" fi exit "$rc" } if [ "$#" -gt 1 ] ; then usage "$0" 1 elif [ "$#" -eq 1 ] ; then if [ "$1" = "-h" -o "$1" = "--help" ] ; then usage "$0" 0 elif [ "$1" = "-n" ] ; then DRY_RUN=1 else usage "$0" 1 fi fi # We can't use a -r test here because while $PROFILES is world-readable, # apparmorfs may still return EACCES from open() # # We have to do this check because error checking awk's getline() below is # tricky and, as is, results in an infinite loop when apparmorfs returns an # error from open(). if ! IFS= read line < "$PROFILES" ; then echo "ERROR: Unable to read apparmorfs profiles file" 1>&2 exit 1 elif [ ! -w "$REMOVE" ] ; then echo "ERROR: Unable to write to apparmorfs remove file" 1>&2 exit 1 fi # Clean out running profiles not associated with the current profile # set, excluding the libvirt dynamically generated profiles. # Note that we reverse sort the list of profiles to remove to # ensure that child profiles (e.g. hats) are removed before the # parent. We *do* need to remove the child profile and not rely # on removing the parent profile when the profile has had its # child profile names changed. profiles_names_list | awk ' BEGIN { while (getline < "'${PROFILES}'" ) { str = sub(/ \((enforce|complain)\)$/, "", $0); if (match($0, /^libvirt-[0-9a-f\-]+$/) == 0) arr[$str] = $str } } { if (length(arr[$0]) > 0) { delete arr[$0] } } END { for (key in arr) if (length(arr[key]) > 0) { printf("%s\n", arr[key]) } } ' | LC_COLLATE=C sort -r | \ while IFS= read profile ; do if [ "$DRY_RUN" -ne 0 ]; then echo "Would remove '${profile}'" else echo "Removing '${profile}'" echo -n "$profile" > "${REMOVE}" fi done # will not catch all errors, but still better than nothing exit $? apparmor-2.13.3/utils/aa-enforce.pod0000644000175000017500000000405013502024172015050 0ustar jjjj# This publication is intellectual property of Novell Inc. and Canonical # Ltd. Its contents can be duplicated, either in part or in whole, provided # that a copyright label is visibly located on each copy. # # All information found in this book has been compiled with utmost # attention to detail. However, this does not guarantee complete accuracy. # Neither SUSE LINUX GmbH, Canonical Ltd, the authors, nor the translators # shall be held liable for possible errors or the consequences thereof. # # Many of the software and hardware descriptions cited in this book # are registered trademarks. All trade names are subject to copyright # restrictions and may be registered trade marks. SUSE LINUX GmbH # and Canonical Ltd. essentially adhere to the manufacturer's spelling. # # Names of products and trademarks appearing in this book (with or without # specific notation) are likewise subject to trademark and trade protection # laws and may thus fall under copyright restrictions. # =pod =head1 NAME aa-enforce - set an AppArmor security profile to I mode from being disabled or I mode. =head1 SYNOPSIS BexecutableE> [IexecutableE> ...] [I<-d /path/to/profiles>] [I<--no-reload>]> =head1 OPTIONS B<-d --dir / path/to/profiles> Specifies where to look for the AppArmor security profile set. Defaults to /etc/apparmor.d. B<--no-reload> Do not reload the profile after modifying it. =head1 DESCRIPTION B is used to set one or more profiles to I mode. This command is only relevant in conjunction with the I utility which sets a profile to complain mode and the I utility which unloads and disables a profile. The default mode for a security policy is enforce and the I utility must be run to change this behavior. =head1 BUGS If you find any bugs, please report them at L. =head1 SEE ALSO apparmor(7), apparmor.d(5), aa-complain(1), aa-disable(1), aa_change_hat(2), and L. =cut apparmor-2.13.3/utils/aa-disable0000755000175000017500000000262213502024172014257 0ustar jjjj#! /usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import argparse import apparmor.tools # setup exception handling from apparmor.fail import enable_aa_exception_handler enable_aa_exception_handler() # setup module translations from apparmor.translations import init_translation _ = init_translation() parser = argparse.ArgumentParser(description=_('Disable the profile for the given programs')) parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) parser.add_argument('program', type=str, nargs='+', help=_('name of program')) parser.add_argument('--no-reload', dest='do_reload', action='store_false', default=True, help=_('Do not unload the profile after modifying it')) args = parser.parse_args() tool = apparmor.tools.aa_tools('disable', args) tool.cmd_disable() apparmor-2.13.3/utils/aa-autodep0000755000175000017500000000301213502024172014307 0ustar jjjj#! /usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import argparse import apparmor.tools # setup exception handling from apparmor.fail import enable_aa_exception_handler enable_aa_exception_handler() # setup module translations from apparmor.translations import init_translation _ = init_translation() parser = argparse.ArgumentParser(description=_('Generate a basic AppArmor profile by guessing requirements')) parser.add_argument('--force', action='store_true', default=False, help=_('overwrite existing profile')) parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) parser.add_argument('program', type=str, nargs='+', help=_('name of program')) parser.add_argument('--no-reload', dest='do_reload', action='store_false', default=True, help=_('Do not reload the profile after modifying it')) args = parser.parse_args() tool = apparmor.tools.aa_tools('autodep', args) tool.cmd_autodep() apparmor-2.13.3/utils/aa-status0000755000175000017500000002120713502024172014177 0ustar jjjj#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2005-2006 Novell/SUSE # Copyright (C) 2011 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import re, os, sys, errno, json # PLEASE NOTE: we try to keep aa-status as minimal as possible, for # environments where installing all of the python utils and python # apparmor module may not make sense. Please think carefully before # importing anything from apparmor; see how the apparmor.fail import is # handled below. # setup exception handling try: from apparmor.fail import enable_aa_exception_handler enable_aa_exception_handler() except ImportError: # just let normal python exceptions happen (LP: #1480492) pass def cmd_enabled(): '''Returns error code if AppArmor is not enabled''' if get_profiles() == {}: sys.exit(2) def cmd_profiled(): '''Prints the number of loaded profiles''' profiles = get_profiles() sys.stdout.write("%d\n" % len(profiles)) if profiles == {}: sys.exit(2) def cmd_enforced(): '''Prints the number of loaded enforcing profiles''' profiles = get_profiles() sys.stdout.write("%d\n" % len(filter_profiles(profiles, 'enforce'))) if profiles == {}: sys.exit(2) def cmd_complaining(): '''Prints the number of loaded non-enforcing profiles''' profiles = get_profiles() sys.stdout.write("%d\n" % len(filter_profiles(profiles, 'complain'))) if profiles == {}: sys.exit(2) def cmd_verbose(): '''Displays multiple data points about loaded profile set''' global verbose verbose = True profiles = get_profiles() processes = get_processes(profiles) stdmsg("%d profiles are loaded." % len(profiles)) for status in ('enforce', 'complain'): filtered_profiles = filter_profiles(profiles, status) stdmsg("%d profiles are in %s mode." % (len(filtered_profiles), status)) for item in filtered_profiles: stdmsg(" %s" % item) stdmsg("%d processes have profiles defined." % len(processes)) for status in ('enforce', 'complain', 'unconfined'): filtered_processes = filter_processes(processes, status) if status == 'unconfined': stdmsg("%d processes are unconfined but have a profile defined." % len(filtered_processes)) else: stdmsg("%d processes are in %s mode." % (len(filtered_processes), status)) # Sort by name, and then by pid filtered_processes.sort(key=lambda x: int(x[0])) filtered_processes.sort(key=lambda x: x[1]) for (pid, profile, exe) in filtered_processes: if exe == profile: profile = "" stdmsg(" %s (%s) %s" % (exe, pid, profile)) if profiles == {}: sys.exit(2) def cmd_json(pretty_output=False): '''Outputs multiple data points about loaded profile set in a machine-readable JSON format''' global verbose profiles = get_profiles() processes = get_processes(profiles) i = { 'version': '1', 'profiles': {}, 'processes': {} } for status in ('enforce', 'complain'): filtered_profiles = filter_profiles(profiles, status) for item in filtered_profiles: i['profiles'][item] = status for status in ('enforce', 'complain', 'unconfined'): filtered_processes = filter_processes(processes, status) for (pid, profile, exe) in filtered_processes: if exe not in i['processes']: i['processes'][exe] = [] i['processes'][exe].append({ 'profile': profile, 'pid': pid, 'status': status }) if pretty_output: sys.stdout.write(json.dumps(i, sort_keys=True, indent=4, separators=(',', ': '))) else: sys.stdout.write(json.dumps(i)) def cmd_pretty_json(): cmd_json(True) def get_profiles(): '''Fetch loaded profiles''' profiles = {} if os.path.exists("/sys/module/apparmor"): stdmsg("apparmor module is loaded.") else: errormsg("apparmor module is not loaded.") sys.exit(1) apparmorfs = find_apparmorfs() if not apparmorfs: errormsg("apparmor filesystem is not mounted.") sys.exit(3) apparmor_profiles = os.path.join(apparmorfs, "profiles") try: f = open(apparmor_profiles) except IOError as e: if e.errno == errno.EACCES: errormsg("You do not have enough privilege to read the profile set.") else: errormsg("Could not open %s: %s" % (apparmor_profiles, os.strerror(e.errno))) sys.exit(4) for p in f.readlines(): match = re.search("^([^\(]+)\s+\((\w+)\)$", p) profiles[match.group(1)] = match.group(2) f.close() return profiles def get_processes(profiles): '''Fetch process list''' processes = {} contents = os.listdir("/proc") for filename in contents: if filename.isdigit(): try: for p in open("/proc/%s/attr/current" % filename).readlines(): match = re.search("^([^\(]+)\s+\((\w+)\)$", p) exe = os.path.realpath("/proc/%s/exe" % filename) if match: processes[filename] = { 'profile' : match.group(1), \ 'exe': exe, \ 'mode' : match.group(2) } elif exe in profiles: # keep only unconfined processes that have a profile defined processes[filename] = { 'profile' : exe, \ 'exe': exe, \ 'mode' : 'unconfined' } except: pass return processes def filter_profiles(profiles, status): '''Return a list of profiles that have a particular status''' filtered = [] for key, value in list(profiles.items()): if value == status: filtered.append(key) filtered.sort() return filtered def filter_processes(processes, status): '''Return a list of processes that have a particular status''' filtered = [] for key, value in list(processes.items()): if value['mode'] == status: filtered.append([key, value['profile'], value['exe']]) return filtered def find_apparmorfs(): '''Finds AppArmor mount point''' for p in open("/proc/mounts","rb").readlines(): if p.split()[2].decode() == "securityfs" and \ os.path.exists(os.path.join(p.split()[1].decode(), "apparmor")): return os.path.join(p.split()[1].decode(), "apparmor") return False def errormsg(message): '''Prints to stderr if verbose mode is on''' global verbose if verbose: sys.stderr.write(message + "\n") def stdmsg(message): '''Prints to stdout if verbose mode is on''' global verbose if verbose: sys.stdout.write(message + "\n") def print_usage(): '''Print usage information''' sys.stdout.write('''Usage: %s [OPTIONS] Displays various information about the currently loaded AppArmor policy. OPTIONS (one only): --enabled returns error code if AppArmor not enabled --profiled prints the number of loaded policies --enforced prints the number of loaded enforcing policies --complaining prints the number of loaded non-enforcing policies --json displays multiple data points in machine-readable JSON format --pretty-json same data as --json, formatted for human consumption as well --verbose (default) displays multiple data points about loaded policy set --help this message ''' % sys.argv[0]) # Main global verbose verbose = False if len(sys.argv) > 2: sys.stderr.write("Error: Too many options.\n") print_usage() sys.exit(1) elif len(sys.argv) == 2: cmd = sys.argv.pop(1) else: cmd = '--verbose' # Command dispatch: commands = { '--enabled' : cmd_enabled, '--profiled' : cmd_profiled, '--enforced' : cmd_enforced, '--complaining' : cmd_complaining, '--json' : cmd_json, '--pretty-json' : cmd_pretty_json, '--verbose' : cmd_verbose, '-v' : cmd_verbose, '--help' : print_usage, '-h' : print_usage } if cmd in commands: commands[cmd]() sys.exit(0) else: sys.stderr.write("Error: Invalid command.\n") print_usage() sys.exit(1) apparmor-2.13.3/utils/aa-decode.80000644000175000017500000001131713502024375014250 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "AA-DECODE 8" .TH AA-DECODE 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa\-decode \- decode hex\-encoded in AppArmor log files .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-decode\fR [option] <\s-1HEX STRING\s0> .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBaa-decode\fR will decode hex-encoded strings as seen in AppArmor log output. It will also take an audit log on standard input and convert any hex-encoded AppArmor log entries and display them on standard output. .SH "OPTIONS" .IX Header "OPTIONS" .IP "\-\-help" 4 .IX Item "--help" displays a short usage statement. .SH "EXAMPLES" .IX Header "EXAMPLES" .Vb 2 \& $ aa\-decode 2F746D702F666F6F20626172 \& Decoded: /tmp/foo bar \& \& $ cat /var/log/kern.log | aa\-decode \& ... denied_mask="r::" fsuid=1000 ouid=1000 name=/tmp/foo bar .Ve .SH "BUGS" .IX Header "BUGS" None. Please report any you find to Launchpad at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7) apparmor-2.13.3/utils/README.md0000644000175000017500000000024313502024172013623 0ustar jjjjKnown Bugs: Will allow multiple letters in the () due to translation/unicode issues with regexing the key. User input will probably bug out in a different locale. apparmor-2.13.3/utils/aa-decode.8.html0000644000175000017500000000416113502024376015213 0ustar jjjj
 

NAME

aa-decode - decode hex-encoded in AppArmor log files

SYNOPSIS

aa-decode [option] <HEX STRING>

DESCRIPTION

aa-decode will decode hex-encoded strings as seen in AppArmor log output. It will also take an audit log on standard input and convert any hex-encoded AppArmor log entries and display them on standard output.

OPTIONS

--help

displays a short usage statement.

EXAMPLES

  $ aa-decode 2F746D702F666F6F20626172
  Decoded: /tmp/foo bar

  $ cat /var/log/kern.log | aa-decode
  ... denied_mask="r::" fsuid=1000 ouid=1000 name=/tmp/foo bar

BUGS

None. Please report any you find to Launchpad at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7)

 
apparmor-2.13.3/utils/aa-enforce.8.html0000644000175000017500000000465713502024376015423 0ustar jjjj
 

NAME

aa-enforce - set an AppArmor security profile to enforce mode from being disabled or complain mode.

SYNOPSIS

aa-enforce <executable> [<executable> ...] [-d /path/to/profiles] [--no-reload]

OPTIONS

-d --dir / path/to/profiles

   Specifies where to look for the AppArmor security profile set.
   Defaults to /etc/apparmor.d.

--no-reload Do not reload the profile after modifying it.

DESCRIPTION

aa-enforce is used to set one or more profiles to enforce mode. This command is only relevant in conjunction with the aa-complain utility which sets a profile to complain mode and the aa-disable utility which unloads and disables a profile. The default mode for a security policy is enforce and the aa-complain utility must be run to change this behavior.

BUGS

If you find any bugs, please report them at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7), apparmor.d(5), aa-complain(1), aa-disable(1), aa_change_hat(2), and https://wiki.apparmor.net.

 
apparmor-2.13.3/utils/python-tools-setup.py0000644000175000017500000000550313502024172016537 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (c) 2012 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Canonical, Ltd. # ---------------------------------------------------------------------- # # Usage: # $ python ./python-tools-setup.py install --root=... --version=... # # Note: --version=... must be the last argument to this script # from distutils.command.install import install as _install from distutils.core import setup import os import shutil import sys class Install(_install, object): '''Override distutils to install the files where we want them.''' def run(self): # Now byte-compile everything super(Install, self).run() prefix = self.prefix if self.root != None: prefix = self.root # Install scripts, configuration files and data scripts = ['/usr/bin/aa-easyprof'] self.mkpath(prefix + os.path.dirname(scripts[0])) for s in scripts: f = prefix + s self.copy_file(os.path.basename(s), f) configs = ['easyprof/easyprof.conf'] self.mkpath(prefix + "/etc/apparmor") for c in configs: self.copy_file(c, os.path.join(prefix + "/etc/apparmor", os.path.basename(c))) data = ['easyprof/templates', 'easyprof/policygroups'] self.mkpath(prefix + "/usr/share/apparmor/easyprof") for d in data: self.copy_tree(d, os.path.join(prefix + "/usr/share/apparmor/easyprof", os.path.basename(d))) if os.path.exists('staging'): shutil.rmtree('staging') shutil.copytree('apparmor', 'staging') # Support the --version=... since this will be part of a Makefile version = "unknown-version" if "--version=" in sys.argv[-1]: version=sys.argv[-1].split('=')[1] sys.argv = sys.argv[0:-1] setup (name='apparmor', version=version, description='Python libraries for AppArmor utilities', long_description='Python libraries for AppArmor utilities', author='AppArmor Developers', author_email='apparmor@lists.ubuntu.com', url='https://launchpad.net/apparmor', license='GPL-2', cmdclass={'install': Install}, package_dir={'apparmor': 'staging'}, packages=['apparmor', 'apparmor.rule'], py_modules=['apparmor.easyprof'] ) shutil.rmtree('staging') apparmor-2.13.3/utils/aa-genprof.80000644000175000017500000001436413502024375014472 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "AA-GENPROF 8" .TH AA-GENPROF 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa\-genprof \- profile generation utility for AppArmor .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-genprof \f(BI\fB [\f(BI\-d /path/to/profiles\fB] [\f(BI\-f /path/to/logfile\fB]\fR .SH "OPTIONS" .IX Header "OPTIONS" \&\fB\-d \-\-dir /path/to/profiles\fR .PP .Vb 2 \& Specifies where to look for the AppArmor security profile set. \& Defaults to /etc/apparmor.d. .Ve .PP \&\fB\-f \-\-file /path/to/logfile\fR .PP .Vb 6 \& Specifies the location of logfile. \& Default locations are read from F. \& Typical defaults are: \& /var/log/audit/audit.log \& /var/log/syslog \& /var/log/messages .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" When running aa-genprof, you must specify a program to profile. If the specified program is not a fully-qualified path, aa-genprof will search \f(CW$PATH\fR in order to find the program. .PP If a profile does not exist for the program, aa-genprof will create one using \&\fIaa\-autodep\fR\|(1). .PP Genprof will then: .PP .Vb 1 \& \- set the profile to complain mode \& \& \- write a mark to the system log \& \& \- instruct the user to start the application to \& be profiled in another window and exercise its functionality .Ve .PP It then presents the user with two options, (S)can system log for entries to add to profile and (F)inish. .PP If the user selects (S)can or hits return, aa-genprof will parse the complain mode logs and iterate through generated violations using \fIaa\-logprof\fR\|(1). .PP After the user finishes selecting profile entries based on violations that were detected during the program execution, aa-genprof will reload the updated profiles in complain mode and again prompt the user for (S)can and (F)inish. This cycle can then be repeated as necessary until all application functionality has been exercised without generating access violations. .PP When the user eventually hits (F)inish, aa-genprof will set the main profile, and any other profiles that were generated, into enforce mode and exit. .SH "BUGS" .IX Header "BUGS" If you find any bugs, please report them at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7), \fIapparmor.d\fR\|(5), \fIaa\-enforce\fR\|(1), \fIaa\-complain\fR\|(1), \fIaa\-disable\fR\|(1), \&\fIaa_change_hat\fR\|(2), \fIaa\-logprof\fR\|(1), \fIlogprof.conf\fR\|(5), and . apparmor-2.13.3/utils/Makefile0000644000175000017500000000641413502024172014012 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (c) 1999, 2004-2009 NOVELL (All rights reserved) # Copyright (c) 2010-2016 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Novell, Inc. # ---------------------------------------------------------------------- NAME = apparmor-utils all: COMMONDIR=../common/ include $(COMMONDIR)/Make.rules PERLTOOLS = aa-notify PYTOOLS = aa-easyprof aa-genprof aa-logprof aa-cleanprof aa-mergeprof \ aa-autodep aa-audit aa-complain aa-enforce aa-disable \ aa-status aa-unconfined TOOLS = ${PERLTOOLS} ${PYTOOLS} aa-decode aa-remove-unknown PYSETUP = python-tools-setup.py PYMODULES = $(wildcard apparmor/*.py apparmor/rule/*.py) MANPAGES = ${TOOLS:=.8} logprof.conf.5 all: docs $(MAKE) -C po all $(MAKE) -C vim all .PHONY: docs docs: ${MANPAGES} ${HTMLMANPAGES} # need some better way of determining this DESTDIR=/ BINDIR=${DESTDIR}/usr/sbin CONFDIR=${DESTDIR}/etc/apparmor PYPREFIX=/usr PYFLAKES=pyflakes po/${NAME}.pot: ${TOOLS} ${PYMODULES} $(MAKE) -C po ${NAME}.pot NAME=${NAME} SOURCES="${TOOLS} ${PYMODULES}" .PHONY: install install: ${MANPAGES} ${HTMLMANPAGES} install -d ${CONFDIR} install -m 644 logprof.conf severity.db notify.conf ${CONFDIR} install -d ${BINDIR} ln -sf aa-status ${BINDIR}/apparmor_status # aa-easyprof is installed by python-tools-setup.py install -m 755 $(filter-out aa-easyprof, ${TOOLS}) ${BINDIR} $(MAKE) -C po install DESTDIR=${DESTDIR} NAME=${NAME} $(MAKE) install_manpages DESTDIR=${DESTDIR} $(MAKE) -C vim install DESTDIR=${DESTDIR} ln -sf aa-status.8 ${DESTDIR}/${MANDIR}/man8/apparmor_status.8 ${PYTHON} ${PYSETUP} install --prefix=${PYPREFIX} --root=${DESTDIR} --version=${VERSION} .PHONY: clean ifndef VERBOSE .SILENT: clean endif clean: pod_clean rm -f core core.* *.o *.s *.a *~ $(MAKE) -C po clean $(MAKE) -C vim clean $(MAKE) -C test clean rm -rf staging/ build/ rm -f apparmor/*.pyc apparmor/rule/*.pyc rm -rf apparmor/__pycache__/ apparmor/rule/__pycache__/ # ${CAPABILITIES} is defined in common/Make.rules .PHONY: check_severity_db .SILENT: check_severity_db check_severity_db: /usr/include/linux/capability.h severity.db # The sed statement is based on the one in the parser's makefile RC=0 ; for cap in ${CAPABILITIES} ; do \ if ! grep -q -w $${cap} severity.db ; then \ echo "Warning! capability $${cap} not found in severity.db" ; \ RC=1 ; \ fi ;\ done ; \ test "$$RC" -eq 0 # check_pod_files is defined in common/Make.rules .PHONY: check .SILENT: check check: check_severity_db check_pod_files for i in ${PERLTOOLS} ; do \ perl -c $$i || exit 1; \ done for i in ${PYTOOLS} apparmor test/*.py; do \ echo Checking $$i; \ $(PYFLAKES) $$i || exit 1; \ done $(MAKE) -C test check $(MAKE) -C vim check apparmor-2.13.3/utils/aa-complain.pod0000644000175000017500000000363013502024172015234 0ustar jjjj# This publication is intellectual property of Novell Inc. and Canonical # Ltd. Its contents can be duplicated, either in part or in whole, provided # that a copyright label is visibly located on each copy. # # All information found in this book has been compiled with utmost # attention to detail. However, this does not guarantee complete accuracy. # Neither SUSE LINUX GmbH, Canonical Ltd, the authors, nor the translators # shall be held liable for possible errors or the consequences thereof. # # Many of the software and hardware descriptions cited in this book # are registered trademarks. All trade names are subject to copyright # restrictions and may be registered trade marks. SUSE LINUX GmbH # and Canonical Ltd. essentially adhere to the manufacturer's spelling. # # Names of products and trademarks appearing in this book (with or without # specific notation) are likewise subject to trademark and trade protection # laws and may thus fall under copyright restrictions. # =pod =head1 NAME aa-complain - set an AppArmor security profile to I mode. =head1 SYNOPSIS BexecutableE> [IexecutableE> ...] [I<-d /path/to/profiles>] [I<--no-reload>]> =head1 OPTIONS B<-d --dir /path/to/profiles> Specifies where to look for the AppArmor security profile set. Defaults to /etc/apparmor.d. B<--no-reload> Do not reload the profile after modifying it. =head1 DESCRIPTION B is used to set the enforcement mode for one or more profiles to I mode. In this mode security policy is not enforced but rather access violations are logged to the system log. Note that 'deny' rules will be enforced even in complain mode. =head1 BUGS If you find any bugs, please report them at L. =head1 SEE ALSO apparmor(7), apparmor.d(5), aa-enforce(1), aa-disable(1), aa_change_hat(2), and L. =cut apparmor-2.13.3/utils/aa-notify0000755000175000017500000005046313502024172014172 0ustar jjjj#!/usr/bin/perl # ------------------------------------------------------------------ # # Copyright (C) 2009-2011 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ # # /etc/apparmor/notify.conf: # # set to 'yes' to enable AppArmor DENIED notifications # show_notifications="yes" # # # only people in use_group can run this script # use_group="admin" # # $HOME/.apparmor/notify.conf can have: # # set to 'yes' to enable AppArmor DENIED notifications # show_notifications="yes" # use strict; use warnings; no warnings qw( once ); require LibAppArmor; require POSIX; require Time::Local; require File::Basename; use Getopt::Long; my %prefs; my $conf = "/etc/apparmor/notify.conf"; my $user_conf = ""; my $notify_exe = "/usr/bin/notify-send"; my $notify_home = ""; my $notify_display = ""; my $last_exe = "/usr/bin/last"; my $ps_exe = "/bin/ps"; my $url = "https://wiki.ubuntu.com/DebuggingApparmor"; my $nobody_user = "nobody"; my $nobody_group = "nogroup"; sub readconf; sub parse_message; sub format_message; sub format_stats; sub kill_running_daemons; sub do_notify; sub show_since; sub do_last; sub do_show_messages; sub _error; sub _warn; sub _debug; sub exitscript; sub usage; # # Main script # # Clean environment $ENV{PATH} = "/bin:/usr/bin"; $ENV{SHELL} = "/bin/sh"; defined($ENV{IFS}) and $ENV{IFS} = ' \t\n'; my $prog = File::Basename::basename($0); if ($prog !~ /^[a-zA-Z0-9_\-]+$/) { print STDERR "ERROR: bad programe name '$prog'\n"; exitscript(1); } $> == $< or die "Cannot be suid\n"; $) == $( or die "Cannot be sgid\n"; my $login; our $orig_euid = $>; my $opt_d = ''; my $opt_display = ''; my $opt_h = ''; my $opt_l = ''; my $opt_p = ''; my $opt_v = ''; my $opt_f = ''; my $opt_s = 0; my $opt_u = ''; my $opt_w = 0; GetOptions( 'debug|d' => \$opt_d, 'display=s' => \$opt_display, 'help|h' => \$opt_h, 'since-last|l' => \$opt_l, 'poll|p' => \$opt_p, 'verbose|v' => \$opt_v, 'file|f=s' => \$opt_f, 'since-days|s=n' => \$opt_s, 'user|u=s' => \$opt_u, 'wait|w=n' => \$opt_w, ); if ($opt_h) { usage; exitscript(0); } # monitor file specified with -f, else use audit.log if auditd is running, # otherwise kern.log our $logfile = "/var/log/kern.log"; if ($opt_f) { -f $opt_f or die "'$opt_f' does not exist. Aborting\n"; $logfile = $opt_f; } else { -e "/var/run/auditd.pid" and $logfile = "/var/log/audit/audit.log"; } -r $logfile or die "Cannot read '$logfile'\n"; our $logfile_inode = get_logfile_inode($logfile); our $logfile_size = get_logfile_size($logfile); open (LOGFILE, "<$logfile") or die "Could not open '$logfile'\n"; # Drop priviliges, if running as root if ($< == 0) { $login = "root"; if (defined($ENV{SUDO_UID}) and defined($ENV{SUDO_GID})) { $) = "$ENV{SUDO_GID} $ENV{SUDO_GID}" or _error("Could not change egid"); $( = $ENV{SUDO_GID} or _error("Could not change gid"); $> = $ENV{SUDO_UID} or _error("Could not change euid"); defined($ENV{SUDO_USER}) and $login = $ENV{SUDO_USER}; } else { my $drop_to = $nobody_user; if ($opt_u) { $drop_to = $opt_u; } # nobody/nogroup my $nam = scalar(getgrnam($nobody_group)); $) = "$nam $nam" or _error("Could not change egid"); $( = $nam or _error("Could not change gid"); $> = scalar(getpwnam($drop_to)) or _error("Could not change euid to '$drop_to'"); } } else { $login = getlogin(); defined $login or $login = $ENV{'USER'}; } if (-s $conf) { readconf($conf); if (defined($prefs{use_group})) { my ($name, $passwd, $gid, $members) = getgrnam($prefs{use_group}); if (not defined($members) or not defined($login) or (not grep { $_ eq $login } split(/ /, $members) and $login ne "root")) { _error("'$login' must be in '$prefs{use_group}' group. Aborting.\nAsk your admin to add you to this group or to change the group in\n$conf if you want to use aa-notify."); } } } # find user's notify.conf if (-e "$ENV{HOME}/.apparmor/notify.conf" ) { # use legacy path if the conf file is there $user_conf = "$ENV{HOME}/.apparmor/notify.conf"; } elsif (defined $ENV{XDG_CONFIG_HOME}) { # use XDG_CONFIG_HOME if it is defined $user_conf = "$ENV{XDG_CONFIG_HOME}/apparmor/notify.conf"; } else { # fallback to the default value of XDG_CONFIG_HOME $user_conf = "$ENV{HOME}/.config/apparmor/notify.conf"; } if ($opt_p) { # notify-send is packaged in libnotify-bin on Debian/Ubuntu, libnotify-tools on openSUSE -x "$notify_exe" or _error("Could not find '$notify_exe'. Please install it (package libnotify-bin or libnotify-tools). Aborting"); # we need correct values for $HOME and $DISPLAY environment variables, # otherwise $notify_exe won't be able to connect to DBUS to display the # message. Do this here to avoid excessive lookups. $notify_home = (getpwuid $>)[7]; # homedir of the user if ($opt_display ne '') { $notify_display = $opt_display; } elsif (defined($ENV{'DISPLAY'})) { $notify_display = $ENV{'DISPLAY'}; } if ($notify_display eq '') { my $sudo_warn_msg = ''; if (defined($ENV{'SUDO_USER'})) { $sudo_warn_msg = ' (or reset by sudo)'; } _warn("Environment variable \$DISPLAY not set$sudo_warn_msg."); _warn ('Desktop notifications will not work.'); if ($sudo_warn_msg ne '') { _warn ('Use sudo aa-notify -p --display "$DISPLAY" to set the environment variable.'); } else { _warn ('Use something like aa-notify -p --display :0 to set the environment variable.') } } } elsif ($opt_l) { -x "$last_exe" or _error("Could not find '$last_exe'. Aborting"); } if ($opt_s and not $opt_l) { $opt_s =~ /^[0-9]+$/ or _error("-s requires a number"); } if ($opt_w) { $opt_w =~ /^[0-9]+$/ or _error("-w requires a number"); } if ($opt_p or $opt_l) { if (-s $user_conf) { readconf($user_conf); } if (defined($prefs{show_notifications}) and $prefs{show_notifications} ne "yes") { _debug("'show_notifications' is disabled. Exiting"); exitscript(0); } } my $now = time(); if ($opt_p) { do_notify(); } elsif ($opt_l) { do_last(); } elsif ($opt_s and not $opt_p) { do_show_messages($opt_s); } else { usage; exitscript(1); } exitscript(0); # # Subroutines # sub readconf { my $cfg = $_[0]; -r $cfg or die "'$cfg' does not exist\n"; open (CFG, "<$cfg") or die "Could not open '$cfg'\n"; while () { chomp; s/#.*//; # no comments s/^\s+//; # no leading white s/\s+$//; # no trailing white next unless length; # anything left? my ($var, $value) = split(/\s*=\s*/, $_, 2); if ($var eq "show_notifications" or $var eq "use_group" or $var eq "message_body" or $var eq "message_title" or $var eq "message_footer") { $value =~ s/^"(.*)"$/$1/g; $prefs{$var} = $value; } } close(CFG); } sub parse_message { my @params = @_; my $msg = $params[0]; chomp($msg); #_debug("processing: $msg"); my ($test) = LibAppArmorc::parse_record($msg); # Don't show logs before certain date my $date = LibAppArmor::aa_log_record::swig_epoch_get($test); my $since = 0; if (defined($date) and $#params > 0 and $params[1] =~ /^[0-9]+$/) { $since = int($params[1]); int($date) >= $since or goto err; } # ignore all but status and denied messages my $type = LibAppArmor::aa_log_record::swig_event_get($test); if ($type != $LibAppArmor::AA_RECORD_DENIED and $type != $LibAppArmor::AA_RECORD_ALLOWED) { goto err; } my $profile = LibAppArmor::aa_log_record::swig_profile_get($test); my $operation = LibAppArmor::aa_log_record::swig_operation_get($test); my $name = LibAppArmor::aa_log_record::swig_name_get($test); my $denied = LibAppArmor::aa_log_record::swig_denied_mask_get($test); my $family = LibAppArmor::aa_log_record::swig_net_family_get($test); my $sock_type = LibAppArmor::aa_log_record::swig_net_sock_type_get($test); LibAppArmorc::free_record($test); return ($profile, $operation, $name, $denied, $family, $sock_type, $date); err: LibAppArmorc::free_record($test); return (); } sub format_message { my ($profile, $operation, $name, $denied, $family, $sock_type, $date) = @_; my $formatted = ""; if (defined($prefs{message_body})) { $formatted .= $prefs{message_body}; } else { defined($profile) and $formatted .= "Profile: $profile\n"; defined($operation) and $formatted .= "Operation: $operation\n"; defined($name) and $formatted .= "Name: $name\n"; defined($denied) and $formatted .= "Denied: $denied\n"; defined($family) and defined ($sock_type) and $formatted .= "Family: $family\nSocket type: $sock_type\n"; $formatted .= "Logfile: $logfile\n"; } return $formatted; } sub format_stats { my $num = $_[0]; my $time = $_[1]; if ($num > 0) { print "AppArmor denial"; $num > 1 and print "s"; print ": $num (since " . scalar(localtime($time)) . ")\n"; $opt_v and print "For more information, please see: $url\n"; } } sub kill_running_daemons { # Look for other daemon instances of this script and kill them. This # can happen on logout and back in (in which case $notify_exe fails # anyway). 'ps xw' should output something like: # 9987 ? Ss 0:01 /usr/bin/perl ./bin/aa-notify -p # 10170 ? Ss 0:00 /usr/bin/perl ./bin/aa-notify -p open(PS,"$ps_exe xw|") or die "Unable to run '$ps_exe':$!\n"; while() { chomp; /$prog -[ps]/ or next; s/^\s+//; my @line = split(/\s+/, $_); if ($line[5] =~ /$prog$/ and ($line[6] eq "-p" or $line[6] eq "-s")) { if ($line[0] != $$) { _warn("killing old daemon '$line[0]'"); kill 15, ($line[0]); } } } close(PS); } sub send_message { my $msg = $_[0]; my $pid = fork(); if ($pid == 0) { # child # notify-send needs $< to be the unprivileged user $< = $>; $notify_home ne "" and $ENV{'HOME'} = $notify_home; $notify_display ne "" and $ENV{'DISPLAY'} = $notify_display; if (not defined($ENV{'DBUS_SESSION_BUS_ADDRESS'})) { $ENV{'DBUS_SESSION_BUS_ADDRESS'} = "unix:path=/run/user/$>/bus"; } # 'system' uses execvp() so no shell metacharacters here. # $notify_exe is an absolute path so execvp won't search PATH. system "$notify_exe", "-i", "gtk-dialog-warning", "-u", "normal", "--", "AppArmor Message", "$msg"; my $exit_code = $? >> 8; exit($exit_code); } # parent waitpid($pid, 0); return $?; } sub do_notify { my %seen; my $seconds = 5; our $time_to_die = 0; print "Starting aa-notify\n"; kill_running_daemons(); # Daemonize, but not if in debug mode if (not $opt_d) { chdir('/') or die "Can't chdir to /: $!"; umask 0; open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!"; #open STDERR, '>/dev/null' or die "Can't write to /dev/null: $!"; my $pid = fork(); exit if $pid; die "Couldn't fork: $!" unless defined($pid); POSIX::setsid() or die "Can't start a new session: $!"; } sub signal_handler { $time_to_die = 1; } $SIG{INT} = $SIG{TERM} = $SIG{HUP} = \&signal_handler; $SIG{'PIPE'} = 'IGNORE'; if ($opt_w) { sleep($opt_w); } my $count = 0; my $footer = exists $prefs{message_footer} ? $prefs{message_footer} : "For more information, please see:\n$url"; my $first_run = 1; my $since = $now; if ($opt_s and int($opt_s) > 0) { $since = $since - (int($opt_s) * 60 * 60 * 24); } for (my $i=0; $time_to_die == 0; $i++) { if ($logfile_inode != get_logfile_inode($logfile)) { _warn("$logfile changed inodes, reopening"); reopen_logfile(); } elsif (get_logfile_size($logfile) < $logfile_size) { _warn("$logfile is smaller, reopening"); reopen_logfile(); } while(my $msg = ) { my @attrib; if ($first_run == 1) { if ($since != $now) { @attrib = parse_message($msg, $since); } } else { @attrib = parse_message($msg); } $#attrib > 0 or next; if ($first_run == 1) { $count++; next; } my ($profile, $operation, $name, $denied, $family, $sock_type, $date) = @attrib; # Rate limit messages by creating a hash whose keys are: # - for files: $profile|$name|$denied| # - for everything else: $profile|$operation|$name|$denied|$family|$sock_type| (as available) # The value for the key is a timestamp (epoch) and we won't show # messages whose key has a timestamp from less than 5 seconds afo my $k = ""; defined($profile) and $k .= "$profile|"; if (defined($name) and defined($denied)) { $k .= "$name|$denied|"; # for file access, don't worry about operation } else { defined($operation) and $k .= "$operation|"; defined($name) and $k .= "$name|"; defined($denied) and $k .= "$denied|"; defined($family) and defined ($sock_type) and $k .= "$family|$sock_type|"; } # don't display same message if seen in last 5 seconds if (not defined($seen{$k})) { $seen{$k} = time(); } else { my $now = time(); $now - $seen{$k} < $seconds and next; $seen{$k} = $now; } my $m = format_message(@attrib); $m ne "" or next; $m .= $footer; my $rc = send_message($m); if ($rc != 0) { _warn("'$notify_exe' exited with error '$rc'"); $time_to_die = 1; last; } } # from seek() in Programming Perl seek(LOGFILE, 0, 1); sleep(1); if ($first_run) { if ($count > 0) { my $m = "$logfile contains $count denied message"; $count > 1 and $m .= "s"; if ($opt_s) { $m .= " in the last "; if ($opt_s > 1) { $m .= "$opt_s days"; } else { $m .= "day"; } } $m .= ". "; $m .= $footer; send_message($m); } $first_run = 0; } # clean out the %seen database every 30 seconds if ($i > 30) { foreach my $k (keys %seen) { my $now = time(); $now - $seen{$k} > $seconds and delete $seen{$k} and _debug("deleted $k"); } $i = 0; _debug("done purging"); foreach my $k (keys %seen) { _debug("remaining key: $k: $seen{$k}"); } } } print STDERR "Stopping aa-notify\n"; } sub show_since { my %msg_hash; my %last_date; my @msg_list; my $count = 0; while(my $msg = ) { my @attrib = parse_message($msg, $_[0]); $#attrib > 0 or next; my $m = format_message(@attrib); $m ne "" or next; my $date = $attrib[6]; if ($opt_v) { if (exists($msg_hash{$m})) { $msg_hash{$m}++; defined($date) and $last_date{$m} = scalar(localtime($date)); } else { $msg_hash{$m} = 1; push(@msg_list, $m); } } $count++; } if ($opt_v) { foreach my $m (@msg_list) { print "$m"; if ($msg_hash{$m} gt 1) { print "($msg_hash{$m} found"; if (exists($last_date{$m})) { print ", most recent from '$last_date{$m}'"; } print ")\n"; } print "\n"; } } return $count; } sub do_last { open(LAST,"$last_exe -F -a $login|") or die "Unable to run $last_exe:$!\n"; my $time = 0; while(my $line = ) { _debug("Checking '$line'"); $line =~ /^$login/ or next; $line !~ /^$login\s+pts.*\s+:[0-9]+\.[0-9]+$/ or next; # ignore xterm and friends my @entry = split(/\s+/, $line); my ($hour, $min, $sec) = (split(/:/, $entry[5]))[0,1,2]; $time = Time::Local::timelocal($sec, $min, $hour, $entry[4], $entry[3], $entry[6]); last; } close(LAST); $time > 0 or _error("Couldn't find last login"); format_stats(show_since($time), $time); } sub do_show_messages { my $since = $now - (int($_[0]) * 60 * 60 * 24); format_stats(show_since($since), $since); } sub _warn { my $msg = $_[0]; print STDERR "aa-notify: WARN: $msg\n"; } sub _error { my $msg = $_[0]; print STDERR "aa-notify: ERROR: $msg\n"; exitscript(1); } sub _debug { $opt_d or return; my $msg = $_[0]; print STDERR "aa-notify: DEBUG: $msg\n"; } sub exitscript { my $rc = $_[0]; close(LOGFILE); exit $rc; } sub usage { my $s = <<'EOF'; USAGE: aa-notify [OPTIONS] Display AppArmor notifications or messages for DENIED entries. OPTIONS: -p, --poll poll AppArmor logs and display notifications --display $DISPLAY set the DISPLAY environment variable to $DISPLAY (might be needed if sudo resets $DISPLAY) -f FILE, --file=FILE search FILE for AppArmor messages -l, --since-last display stats since last login -s NUM, --since-days=NUM show stats for last NUM days (can be used alone or with -p) -v, --verbose show messages with stats -h, --help display this help -u USER, --user=USER user to drop privileges to when not using sudo -w NUM, --wait=NUM wait NUM seconds before displaying notifications (with -p) EOF print $s; } sub raise_privileges { my $old_euid = -1; if ($> != $<) { _debug("raising privileges to '$orig_euid'"); $old_euid = $>; $> = $orig_euid; $> == $orig_euid or die "Could not raise privileges\n"; } return $old_euid; } sub drop_privileges { my $old_euid = $_[0]; # Just exit if we didn't raise privileges $old_euid == -1 and return; _debug("dropping privileges to '$old_euid'"); $> = $old_euid; $> == $old_euid or die "Could not drop privileges\n"; } sub reopen_logfile { # reopen the logfile, temporarily switching back to starting euid for # file permissions. close(LOGFILE); my $old_euid = raise_privileges(); $logfile_inode = get_logfile_inode($logfile); $logfile_size = get_logfile_size($logfile); open (LOGFILE, "<$logfile") or die "Could not open '$logfile'\n"; drop_privileges($old_euid); } sub get_logfile_size { my $fn = $_[0]; my $size; my $dir = File::Basename::dirname($fn); # If we can't access the file, then raise privs. This can happen when # using auditd and /var/log/audit/ is 700. my $old_euid = -1; if (! -x $dir) { $old_euid = raise_privileges(); } defined(($size = (stat($fn))[7])) or (sleep(10) and defined(($size = (stat($fn))[7])) or die "'$fn' disappeared. Aborting\n"); drop_privileges($old_euid); return $size; } sub get_logfile_inode { my $fn = $_[0]; my $inode; my $dir = File::Basename::dirname($fn); # If we can't access the file, then raise privs. This can happen when # using auditd and /var/log/audit/ is 700. my $old_euid = -1; if (! -x $dir) { $old_euid = raise_privileges(); } defined(($inode = (stat($fn))[1])) or (sleep(10) and defined(($inode = (stat($fn))[1])) or die "'$fn' disappeared. Aborting\n"); drop_privileges($old_euid); return $inode; } # # end Subroutines # apparmor-2.13.3/utils/aa-disable.80000644000175000017500000001164713502024375014436 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "AA-DISABLE 8" .TH AA-DISABLE 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa\-disable \- disable an AppArmor security profile .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-disable \f(BI\fB [\f(BI\fB ...] [\f(BI\-d /path/to/profiles\fB] [\f(BI\-\-no\-reload\fB] [\f(BI\-r\fB]\fR .SH "OPTIONS" .IX Header "OPTIONS" \&\fB\-d \-\-dir /path/to/profiles\fR .PP .Vb 2 \& Specifies where to look for the AppArmor security profile set. \& Defaults to /etc/apparmor.d. .Ve .PP \&\fB\-\-no\-reload\fR Do not unreload the profile after modifying it. .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBaa-disable\fR is used to \fIdisable\fR one or more profiles. This command will unload the profile from the kernel and prevent the profile from being loaded on AppArmor startup. The \fIaa-enforce\fR and \fIaa-complain\fR utilities may be used to to change this behavior. .SH "BUGS" .IX Header "BUGS" If you find any bugs, please report them at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7), \fIapparmor.d\fR\|(5), \fIaa\-enforce\fR\|(1), \fIaa\-complain\fR\|(1), \&\fIaa_change_hat\fR\|(2), and . apparmor-2.13.3/utils/aa-logprof.8.html0000644000175000017500000001736613502024375015452 0ustar jjjj
 

NAME

aa-logprof - utility for updating AppArmor security profiles

SYNOPSIS

aa-logprof [-d /path/to/profiles] [-f /path/to/logfile] [-m <mark in logfile>]

OPTIONS

-d --dir /path/to/profiles

   Specifies where to look for the AppArmor security profile set.
   Defaults to /etc/apparmor.d.

-f --file /path/to/logfile

    Specifies the location of logfile that contains AppArmor security events.
        Default locations are read from F</etc/apparmor/logprof.conf>.
        Typical defaults are:
                 /var/log/audit/audit.log
                 /var/log/syslog
                 /var/log/messages

-m --logmark "mark"

   aa-logprof will ignore all events in the system log before the
   specified mark is seen.  If the mark contains spaces, it must 
   be surrounded with quotes to work correctly.

DESCRIPTION

aa-logprof is an interactive tool used to review AppArmor generated messages and update AppArmor security profiles.

Running aa-logprof will scan the log file and if there are new AppArmor events that are not covered by the existing profile set, the user will be prompted with suggested modifications to augment the profile.

When aa-logprof exits profile changes are saved to disk. If AppArmor is running, the updated profiles are reloaded and if any processes that generated AppArmor events are still running in the null-complain-profile, those processes are set to run under their proper profiles.

Responding to AppArmor Events

aa-logprof will generate a list of suggested profile changes that the user can choose from, or they can create their own, to modifiy the permission set of the profile so that the generated access violation will not re-occur.

The user is then presented with info about the access including profile, path, old mode if there was a previous entry in the profile for this path, new mode, the suggestion list, and given these options:

   (A)llow, (D)eny, (I)gnore, (N)ew, (G)lob last piece, (Q)uit

If the AppArmor profile was in complain mode when the event was generated, the default for this option is (A)llow, otherwise, it's (D)eny.

The (D)eny option adds a "deny" rule to the AppArmor profile, which silences logging.

The (I)gnore option allows user to ignore the event, without making any changes to the AppArmor profile.

The suggestion list is presented as a numbered list with includes at the top, the literal path in the middle, and the suggested globs at the bottom. If any globs are being suggested, the shortest glob is the selected option, otherwise, the literal path is selected. Picking includes from the list must be done manually.

Hitting a numbered key will change the selected option to the corresponding numbered entry in the list.

If the user selects (N)ew, they'll be prompted to enter their own globbed entry to match the path. If the user-entered glob does not match the path for this event, they'll be informed and have the option to fix it.

If the user selects (G)lob last piece then, taking the currently selected option, aa-logprof will remove the last path element and replace it with /*.

If the last path element already was /*, aa-logprof will go up a directory level and replace it with /**.

This new globbed entry is then added to the suggestion list and marked as the selected option.

So /usr/share/themes/foo/bar/baz.gif can be turned into /usr/share/themes/** by hitting "g" three times.

If the user selects (A)llow, aa-logprof will take the current selection and add it to the profile, deleting other entries in the profile that are matched by the new entry.

Adding r access to /usr/share/themes/** would delete an entry for r access to /usr/share/themes/foo/*.gif if it exists in the profile.

If (Q)uit is selected at this point, aa-logprof will ignore all new pending accesses.

After all of the accesses have been handled, logrof will write all updated profiles to the disk and reload them if AppArmor is running.

New Process (Execution) Events

If there are unhandled x accesses generated by the execve(2) of a new process, aa-logprof will display the parent profile and the target program that's being executed and prompt the user to select an execute modifier. These modifiers will allow a choice for the target to: have it's own profile (px), inherit the parent's profile (ix), run unconstrained (ux), or deny access for the target. See apparmor.d(5) for details.

If there is a corresponding entry for the target in the qualifiers section of /etc/apparmor/logprof.conf, the presented list will contain only the allowed modes.

The default option for this question is selected using this logic--

  # if px mode is allowed and profile exists for the target
  #   px is default.
  # else if ix mode is allowed
  #   ix is default
  # else
  #   deny is default

aa-logprof will never suggest "ux" as the default.

ChangeHat Events

If unknown aa_change_hat(2) events are found, the user is prompted to add a new hat, if the events should go into the default hat for this profile based on the corresponding entry in the defaulthat section of logprof.conf, or if the following events that run under that hat should be denied altogether.

Capability Events

If there are capability accesses, the user is shown each capability access and asked if the capability should be allowed, denied, or if the user wants to quit. See capability(7) for details.

BUGS

If you find any bugs, please report them at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

klogd(8), auditd(8), apparmor(7), apparmor.d(5), aa_change_hat(2), logprof.conf(5), aa-genprof(1), aa-enforce(1), aa-complain(1), aa-disable(1), and https://wiki.apparmor.net.

 
apparmor-2.13.3/utils/aa-mergeprof0000755000175000017500000001616713502024172014653 0ustar jjjj#! /usr/bin/python3 # ---------------------------------------------------------------------- # Copyright (C) 2013 Kshitij Gupta # Copyright (C) 2014-2018 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # ---------------------------------------------------------------------- import argparse import os import apparmor.aa import apparmor.aamode import apparmor.severity import apparmor.cleanprofile as cleanprofile import apparmor.ui as aaui from apparmor.common import AppArmorException from apparmor.regex import re_match_include # setup exception handling from apparmor.fail import enable_aa_exception_handler enable_aa_exception_handler() # setup module translations from apparmor.translations import init_translation _ = init_translation() parser = argparse.ArgumentParser(description=_('Merge the given profiles into /etc/apparmor.d/ (or the directory specified with -d)')) parser.add_argument('files', nargs='+', type=str, help=_('Profile(s) to merge')) parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) #parser.add_argument('-a', '--auto', action='store_true', help=_('Automatically merge profiles, exits incase of *x conflicts')) args = parser.parse_args() args.other = None apparmor.aa.init_aa() profiles = args.files profiledir = args.dir if profiledir: apparmor.aa.profile_dir = apparmor.aa.get_full_path(profiledir) if not os.path.isdir(apparmor.aa.profile_dir): raise AppArmorException(_("%s is not a directory.") %profiledir) def reset_aa(): apparmor.aa.aa = apparmor.aa.hasher() apparmor.aa.filelist = apparmor.aa.hasher() apparmor.aa.include = dict() apparmor.aa.active_profiles = apparmor.aa.ProfileList() apparmor.aa.original_aa = apparmor.aa.hasher() def find_profiles_from_files(files): profile_to_filename = dict() for file_name in files: apparmor.aa.read_profile(file_name, True) for profile_name in apparmor.aa.filelist[file_name]['profiles'].keys(): profile_to_filename[profile_name] = file_name reset_aa() return profile_to_filename def find_files_from_profiles(profiles): profile_to_filename = dict() apparmor.aa.read_profiles() for profile_name in profiles: profile_to_filename[profile_name] = apparmor.aa.get_profile_filename_from_profile_name(profile_name, True) reset_aa() return profile_to_filename def main(): base_profile_to_file = find_profiles_from_files(profiles) profiles_to_merge = set(base_profile_to_file.keys()) user_profile_to_file = find_files_from_profiles(profiles_to_merge) for profile_name in profiles_to_merge: aaui.UI_Info("\n\n" + _("Merging profile for %s" % profile_name)) user_file = user_profile_to_file[profile_name] base_file = base_profile_to_file.get(profile_name, None) act([user_file, base_file], profile_name) reset_aa() def act(files, merging_profile): mergeprofiles = Merge(files) #Get rid of common/superfluous stuff mergeprofiles.clear_common() # if not args.auto: if 1 == 1: # workaround to avoid lots of whitespace changes mergeprofiles.ask_merge_questions() q = aaui.PromptQuestion() q.title = _('Changed Local Profiles') q.explanation = _('The following local profiles were changed. Would you like to save them?') q.functions = ['CMD_SAVE_CHANGES', 'CMD_VIEW_CHANGES', 'CMD_ABORT', 'CMD_IGNORE_ENTRY'] q.default = 'CMD_VIEW_CHANGES' q.options = [merging_profile] q.selected = 0 ans = '' arg = None programs = list(mergeprofiles.user.aa.keys()) program = programs[0] while ans != 'CMD_SAVE_CHANGES': ans, arg = q.promptUser() if ans == 'CMD_SAVE_CHANGES': apparmor.aa.write_profile_ui_feedback(program) apparmor.aa.reload_base(program) elif ans == 'CMD_VIEW_CHANGES': for program in programs: apparmor.aa.original_aa[program] = apparmor.aa.deepcopy(apparmor.aa.aa[program]) #oldprofile = apparmor.serialize_profile(apparmor.original_aa[program], program, '') newprofile = apparmor.aa.serialize_profile(mergeprofiles.user.aa[program], program, '') aaui.UI_Changes(mergeprofiles.user.filename, newprofile, comments=True) elif ans == 'CMD_IGNORE_ENTRY': break class Merge(object): def __init__(self, profiles): user, base = profiles #Read and parse base profile and save profile data, include data from it and reset them apparmor.aa.read_profile(base, True) self.base = cleanprofile.Prof(base) reset_aa() #Read and parse user profile apparmor.aa.read_profile(user, True) self.user = cleanprofile.Prof(user) def clear_common(self): deleted = 0 #Remove off the parts in base profile which are common/superfluous from user profile user_base = cleanprofile.CleanProf(False, self.user, self.base) deleted += user_base.compare_profiles() def ask_merge_questions(self): other = self.base log_dict = {'merge': other.aa} apparmor.aa.loadincludes() done = False #Add the file-wide includes from the other profile to the user profile options = [] for inc in other.filelist[other.filename]['include'].keys(): if not inc in self.user.filelist[self.user.filename]['include'].keys(): if inc.startswith('/'): options.append('#include "%s"' %inc) else: options.append('#include <%s>' %inc) default_option = 1 q = aaui.PromptQuestion() q.options = options q.selected = default_option - 1 q.headers = [_('File includes'), _('Select the ones you wish to add')] q.functions = ['CMD_ALLOW', 'CMD_IGNORE_ENTRY', 'CMD_ABORT', 'CMD_FINISHED'] q.default = 'CMD_ALLOW' while not done and options: ans, selected = q.promptUser() if ans == 'CMD_IGNORE_ENTRY': done = True elif ans == 'CMD_ALLOW': selection = options[selected] inc = re_match_include(selection) self.user.filelist[self.user.filename]['include'][inc] = True options.pop(selected) aaui.UI_Info(_('Adding %s to the file.') % selection) elif ans == 'CMD_FINISHED': return if not apparmor.aa.sev_db: apparmor.aa.sev_db = apparmor.severity.Severity(apparmor.aa.CONFDIR + '/severity.db', _('unknown')) apparmor.aa.ask_the_questions(log_dict) if __name__ == '__main__': main() apparmor-2.13.3/utils/aa-easyprof.80000644000175000017500000003561213502024374014660 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "AA-EASYPROF 8" .TH AA-EASYPROF 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa\-easyprof \- AppArmor profile generation made easy. .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-easyprof\fR [option] .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBaa-easyprof\fR provides an easy to use interface for AppArmor policy generation. \fBaa-easyprof\fR supports the use of templates and policy groups to quickly profile an application. Please note that while this tool can help with policy generation, its utility is dependent on the quality of the templates, policy groups and abstractions used. Also, this tool may create policy which is less restricted than creating policy by hand or with \&\fBaa-genprof\fR and \fBaa-logprof\fR. .SH "OPTIONS" .IX Header "OPTIONS" \&\fBaa-easyprof\fR accepts the following arguments: .IP "\-t \s-1TEMPLATE,\s0 \-\-template=TEMPLATE" 4 .IX Item "-t TEMPLATE, --template=TEMPLATE" Specify which template to use. May specify either a system template from /usr/share/apparmor/easyprof/templates or a filename for the template to use. If not specified, use /usr/share/apparmor/easyprof/templates/default. .IP "\-p \s-1POLICYGROUPS,\s0 \-\-policy\-groups=POLICYGROUPS" 4 .IX Item "-p POLICYGROUPS, --policy-groups=POLICYGROUPS" Specify \s-1POLICY\s0 as a comma-separated list of policy groups. See \-\-list\-templates for supported policy groups. The available policy groups are in /usr/share/apparmor/easyprof/policy. Policy groups are simply groupings of AppArmor rules or policies. They are similar to AppArmor abstractions, but usually encompass more policy rules. .IP "\-\-parser \s-1PATH\s0" 4 .IX Item "--parser PATH" Specify the \s-1PATH\s0 of the apparmor_parser binary to use when verifying policy. If this option is not specified, aa-easyprof will attempt to locate the path starting with /sbin/apparmor_parser. .IP "\-a \s-1ABSTRACTIONS,\s0 \-\-abstractions=ABSTRACTIONS" 4 .IX Item "-a ABSTRACTIONS, --abstractions=ABSTRACTIONS" Specify \s-1ABSTRACTIONS\s0 as a comma-separated list of AppArmor abstractions. It is usually recommended you use policy groups instead, but this is provided as a convenience. AppArmor abstractions are located in /etc/apparmor.d/abstractions. See \fIapparmor.d\fR\|(5) for details. .IP "\-b \s-1PATH,\s0 \-\-base=PATH" 4 .IX Item "-b PATH, --base=PATH" Set the base \s-1PATH\s0 for resolving abstractions specified by \-\-abstractions. See the same option in \fIapparmor_parser\fR\|(8) for details. .IP "\-I \s-1PATH,\s0 \-\-Include=PATH" 4 .IX Item "-I PATH, --Include=PATH" Add \s-1PATH\s0 to the search paths used for resolving abstractions specified by \&\-\-abstractions. See the same option in \fIapparmor_parser\fR\|(8) for details. .IP "\-r \s-1PATH,\s0 \-\-read\-path=PATH" 4 .IX Item "-r PATH, --read-path=PATH" Specify a \s-1PATH\s0 to allow owner reads. May be specified multiple times. If the \&\s-1PATH\s0 ends in a '/', then \s-1PATH\s0 is treated as a directory and reads are allowed to all files under this directory. Can optionally use '/*' at the end of the \&\s-1PATH\s0 to only allow reads to files directly in \s-1PATH.\s0 .IP "\-w \s-1PATH,\s0 \-\-write\-dir=PATH" 4 .IX Item "-w PATH, --write-dir=PATH" Like \-\-read\-path but also allow owner writes in additions to reads. .IP "\-n \s-1NAME,\s0 \-\-name=NAME" 4 .IX Item "-n NAME, --name=NAME" Specify \s-1NAME\s0 of policy. If not specified, \s-1NAME\s0 is set to the name of the binary. The \s-1NAME\s0 of the policy is typically only used for profile meta data and does not specify the AppArmor profile name. .IP "\-\-profile\-name=PROFILENAME" 4 .IX Item "--profile-name=PROFILENAME" Specify the AppArmor profile name. When set, uses 'profile \s-1PROFILENAME\s0' in the profile. When set and specifying a binary, uses 'profile \s-1PROFILENAME BINARY\s0' in the profile. If not set, the binary will be used as the profile name and profile attachment. .ie n .IP "\-\-template\-var=""@{\s-1VAR\s0}=VALUE""" 4 .el .IP "\-\-template\-var=``@{\s-1VAR\s0}=VALUE''" 4 .IX Item "--template-var=@{VAR}=VALUE" Set \s-1VAR\s0 to \s-1VALUE\s0 in the resulting policy. This typically only makes sense if the specified template uses this value. May be specified multiple times. .IP "\-\-list\-templates" 4 .IX Item "--list-templates" List available templates. .IP "\-\-show\-template" 4 .IX Item "--show-template" Display template specified with \-\-template. .IP "\-\-templates\-dir=PATH" 4 .IX Item "--templates-dir=PATH" Use \s-1PATH\s0 instead of system templates directory. .IP "\-\-include\-templates\-dir=PATH" 4 .IX Item "--include-templates-dir=PATH" Include \s-1PATH\s0 when searching for templates in addition to the system templates directory (or the one specified with \-\-templates\-dir). System templates will match before those in \s-1PATH.\s0 .IP "\-\-list\-policy\-groups" 4 .IX Item "--list-policy-groups" List available policy groups. .IP "\-\-show\-policy\-group" 4 .IX Item "--show-policy-group" Display policy groups specified with \-\-policy\-groups. .IP "\-\-policy\-groups\-dir=PATH" 4 .IX Item "--policy-groups-dir=PATH" Use \s-1PATH\s0 instead of system policy-groups directory. .IP "\-\-include\-policy\-groups\-dir=PATH" 4 .IX Item "--include-policy-groups-dir=PATH" Include \s-1PATH\s0 when searching for policy groups in addition to the system policy-groups directory (or the one specified with \-\-policy\-groups\-dir). System policy-groups will match before those in \s-1PATH.\s0 .IP "\-\-policy\-version=VERSION" 4 .IX Item "--policy-version=VERSION" Must be used with \-\-policy\-vendor and is used to specify the version of policy groups and templates. When specified, \fBaa-easyprof\fR looks for the subdirectory \&\s-1VENDOR/VERSION\s0 within the policy-groups and templates directory. The specified version must be a positive decimal number compatible with the \s-1JSON\s0 Number type. Eg, when using: .Sp .Vb 4 \& $ aa\-easyprof \-\-templates\-dir=/usr/share/apparmor/easyprof/templates \e \& \-\-policy\-groups\-dir=/usr/share/apparmor/easyprof/policygroups \e \& \-\-policy\-vendor="foo" \e \& \-\-policy\-version=1.0 .Ve .Sp Then /usr/share/apparmor/easyprof/templates/foo/1.0 will be searched for templates and /usr/share/apparmor/easyprof/policygroups/foo/1.0 for policy groups. .IP "\-\-policy\-vendor=VENDOR" 4 .IX Item "--policy-vendor=VENDOR" Must be used with \-\-policy\-version and is used to specify the vendor for policy groups and templates. See \-\-policy\-version for more information. .IP "\-\-author" 4 .IX Item "--author" Specify author of the policy. .IP "\-\-copyright" 4 .IX Item "--copyright" Specify copyright of the policy. .IP "\-\-comment" 4 .IX Item "--comment" Specify comment for the policy. .IP "\-m \s-1MANIFEST,\s0 \-\-manifest=MANIFEST" 4 .IX Item "-m MANIFEST, --manifest=MANIFEST" \&\fBaa-easyprof\fR also supports using a \s-1JSON\s0 manifest file for specifying options related to policy. Unlike command line arguments, the \s-1JSON\s0 file may specify multiple profiles. The structure of the \s-1JSON\s0 is: .Sp .Vb 12 \& { \& "security": { \& "profiles": { \& "": { \& ... attributes specific to this profile ... \& }, \& "": { \& ... \& } \& } \& } \& } .Ve .Sp Each profile \s-1JSON\s0 object (ie, everything under a profile name) may specify any fields related to policy. The \*(L"security\*(R" \s-1JSON\s0 container object is optional and may be omitted. An example manifest file demonstrating all fields is: .Sp .Vb 10 \& { \& "security": { \& "profiles": { \& "com.example.foo": { \& "abstractions": [ \& "audio", \& "gnome" \& ], \& "author": "Your Name", \& "binary": "/opt/foo/**", \& "comment": "Unstructured single\-line comment", \& "copyright": "Unstructured single\-line copyright statement", \& "name": "My Foo App", \& "policy_groups": [ \& "networking", \& "user\-application" \& ], \& "policy_vendor": "somevendor", \& "policy_version": 1.0, \& "read_path": [ \& "/tmp/foo_r", \& "/tmp/bar_r/" \& ], \& "template": "user\-application", \& "template_variables": { \& "APPNAME": "foo", \& "VAR1": "bar", \& "VAR2": "baz" \& }, \& "write_path": [ \& "/tmp/foo_w", \& "/tmp/bar_w/" \& ] \& } \& } \& } \& } .Ve .Sp A manifest file does not have to include all the fields. Eg, a manifest file for an Ubuntu \s-1SDK\s0 application might be: .Sp .Vb 10 \& { \& "security": { \& "profiles": { \& "com.ubuntu.developer.myusername.MyCoolApp": { \& "policy_groups": [ \& "networking", \& "online\-accounts" \& ], \& "policy_vendor": "ubuntu", \& "policy_version": 1.0, \& "template": "ubuntu\-sdk", \& "template_variables": { \& "APPNAME": "MyCoolApp", \& "APPVERSION": "0.1.2" \& } \& } \& } \& } \& } .Ve .IP "\-\-verify\-manifest" 4 .IX Item "--verify-manifest" When used with \-\-manifest, warn about potentially unsafe definitions in the manifest file. .IP "\-\-output\-format=FORMAT" 4 .IX Item "--output-format=FORMAT" Specify either \fBtext\fR (default if unspecified) for AppArmor policy output or \&\fBjson\fR for \s-1JSON\s0 manifest format. .IP "\-\-output\-directory=DIR" 4 .IX Item "--output-directory=DIR" Specify output directory for profile. If unspecified, policy is sent to stdout. .SH "EXAMPLES" .IX Header "EXAMPLES" Example usage for a program named 'foo' which is installed in /opt/foo: .PP .Vb 3 \& $ aa\-easyprof \-\-template=user\-application \-\-template\-var="@{APPNAME}=foo" \e \& \-\-policy\-groups=opt\-application,user\-application \e \& /opt/foo/bin/FooApp .Ve .PP When using a manifest file: .PP .Vb 1 \& $ aa\-easyprof \-\-manifest=manifest.json .Ve .PP To output a manifest file based on aa-easyprof arguments: .PP .Vb 10 \& $ aa\-easyprof \-\-output\-format=json \e \& \-\-author="Your Name" \e \& \-\-comment="Unstructured single\-line comment" \e \& \-\-copyright="Unstructured single\-line copyright statement" \e \& \-\-name="My Foo App" \e \& \-\-profile\-name="com.example.foo" \e \& \-\-template="user\-application" \e \& \-\-policy\-groups="user\-application,networking" \e \& \-\-abstractions="audio,gnome" \e \& \-\-read\-path="/tmp/foo_r" \e \& \-\-read\-path="/tmp/bar_r/" \e \& \-\-write\-path="/tmp/foo_w" \e \& \-\-write\-path=/tmp/bar_w/ \e \& \-\-template\-var="@{APPNAME}=foo" \e \& \-\-template\-var="@{VAR1}=bar" \e \& \-\-template\-var="@{VAR2}=baz" \e \& "/opt/foo/**" .Ve .SH "BUGS" .IX Header "BUGS" If you find any additional bugs, please report them to Launchpad at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7) \fIapparmor.d\fR\|(5) apparmor-2.13.3/utils/aa-notify.8.html0000644000175000017500000000765313502024375015310 0ustar jjjj
 

NAME

aa-notify - display information about logged AppArmor messages.

SYNOPSIS

aa-notify [option]

DESCRIPTION

aa-notify will display a summary or provide desktop notifications for AppArmor DENIED messages.

OPTIONS

aa-notify accepts the following arguments:

-p, --poll

poll AppArmor logs and display desktop notifications. Can be used with '-s' option to display a summary on startup.

--display $DISPLAY

set the DISPLAY environment variable to $DISPLAY (might be needed if sudo resets $DISPLAY)

-f FILE, --file=FILE

search FILE for AppArmor messages

-l, --since-last

show summary since last login.

-s NUM, --since-days=NUM

show summary for last NUM of days.

-u USER, --user=USER

user to drop privileges to when running privileged. When used with the -p option, this should be set to the user that will receive desktop notifications. This has no effect when running under sudo.

-w NUM, --wait=NUM

wait NUM seconds before displaying notifications (for use with -p)

-v, --verbose

show messages with summaries.

-h, --help

displays a short usage statement.

CONFIGURATION

System-wide configuration for aa-notify is done via /etc/apparmor/notify.conf:

  # set to 'yes' to enable AppArmor DENIED notifications
  show_notifications="yes"

  # only people in use_group can use aa-notify
  use_group="admin"

  # OPTIONAL - custom notification message body
  message_body="This is a custom notification message."

  # OPTIONAL - custom notification message footer
  message_footer="For more information visit https://foo.com"

Per-user configuration is done via $XDG_CONFIG_HOME/apparmor/notify.conf (or the deprecated ~/.apparmor/notify.conf if it exists):

  # set to 'yes' to enable AppArmor DENIED notifications
  show_notifications="yes"

BUGS

aa-notify needs to be able to read the logfiles containing the AppArmor DENIED messages.

If you find any additional bugs, please report them to Launchpad at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7)

 
apparmor-2.13.3/utils/aa-logprof.80000644000175000017500000002404513502024375014477 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "AA-LOGPROF 8" .TH AA-LOGPROF 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa\-logprof \- utility for updating AppArmor security profiles .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-logprof [\f(BI\-d /path/to/profiles\fB] [\f(BI\-f /path/to/logfile\fB] [\f(BI\-m \fB]\fR .SH "OPTIONS" .IX Header "OPTIONS" \&\fB\-d \-\-dir /path/to/profiles\fR .PP .Vb 2 \& Specifies where to look for the AppArmor security profile set. \& Defaults to /etc/apparmor.d. .Ve .PP \&\fB\-f \-\-file /path/to/logfile\fR .PP .Vb 6 \& Specifies the location of logfile that contains AppArmor security events. \& Default locations are read from F. \& Typical defaults are: \& /var/log/audit/audit.log \& /var/log/syslog \& /var/log/messages .Ve .PP \&\fB \-m \-\-logmark \*(L"mark\*(R"\fR .PP .Vb 3 \& aa\-logprof will ignore all events in the system log before the \& specified mark is seen. If the mark contains spaces, it must \& be surrounded with quotes to work correctly. .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBaa-logprof\fR is an interactive tool used to review AppArmor generated messages and update AppArmor security profiles. .PP Running aa-logprof will scan the log file and if there are new AppArmor events that are not covered by the existing profile set, the user will be prompted with suggested modifications to augment the profile. .PP When aa-logprof exits profile changes are saved to disk. If AppArmor is running, the updated profiles are reloaded and if any processes that generated AppArmor events are still running in the null-complain-profile, those processes are set to run under their proper profiles. .SS "Responding to AppArmor Events" .IX Subsection "Responding to AppArmor Events" \&\fBaa-logprof\fR will generate a list of suggested profile changes that the user can choose from, or they can create their own, to modifiy the permission set of the profile so that the generated access violation will not re-occur. .PP The user is then presented with info about the access including profile, path, old mode if there was a previous entry in the profile for this path, new mode, the suggestion list, and given these options: .PP .Vb 1 \& (A)llow, (D)eny, (I)gnore, (N)ew, (G)lob last piece, (Q)uit .Ve .PP If the AppArmor profile was in complain mode when the event was generated, the default for this option is (A)llow, otherwise, it's (D)eny. .PP The (D)eny option adds a \*(L"deny\*(R" rule to the AppArmor profile, which silences logging. .PP The (I)gnore option allows user to ignore the event, without making any changes to the AppArmor profile. .PP The suggestion list is presented as a numbered list with includes at the top, the literal path in the middle, and the suggested globs at the bottom. If any globs are being suggested, the shortest glob is the selected option, otherwise, the literal path is selected. Picking includes from the list must be done manually. .PP Hitting a numbered key will change the selected option to the corresponding numbered entry in the list. .PP If the user selects (N)ew, they'll be prompted to enter their own globbed entry to match the path. If the user-entered glob does not match the path for this event, they'll be informed and have the option to fix it. .PP If the user selects (G)lob last piece then, taking the currently selected option, aa-logprof will remove the last path element and replace it with /*. .PP If the last path element already was /*, aa-logprof will go up a directory level and replace it with /**. .PP This new globbed entry is then added to the suggestion list and marked as the selected option. .PP So /usr/share/themes/foo/bar/baz.gif can be turned into /usr/share/themes/** by hitting \*(L"g\*(R" three times. .PP If the user selects (A)llow, aa-logprof will take the current selection and add it to the profile, deleting other entries in the profile that are matched by the new entry. .PP Adding r access to /usr/share/themes/** would delete an entry for r access to /usr/share/themes/foo/*.gif if it exists in the profile. .PP If (Q)uit is selected at this point, aa-logprof will ignore all new pending accesses. .PP After all of the accesses have been handled, logrof will write all updated profiles to the disk and reload them if AppArmor is running. .SS "New Process (Execution) Events" .IX Subsection "New Process (Execution) Events" If there are unhandled x accesses generated by the \fIexecve\fR\|(2) of a new process, aa-logprof will display the parent profile and the target program that's being executed and prompt the user to select an execute modifier. These modifiers will allow a choice for the target to: have it's own profile (px), inherit the parent's profile (ix), run unconstrained (ux), or deny access for the target. See \fIapparmor.d\fR\|(5) for details. .PP If there is a corresponding entry for the target in the qualifiers section of /etc/apparmor/logprof.conf, the presented list will contain only the allowed modes. .PP The default option for this question is selected using this logic\*(-- .PP .Vb 6 \& # if px mode is allowed and profile exists for the target \& # px is default. \& # else if ix mode is allowed \& # ix is default \& # else \& # deny is default .Ve .PP aa-logprof will never suggest \*(L"ux\*(R" as the default. .SS "ChangeHat Events" .IX Subsection "ChangeHat Events" If unknown \fIaa_change_hat\fR\|(2) events are found, the user is prompted to add a new hat, if the events should go into the default hat for this profile based on the corresponding entry in the defaulthat section of logprof.conf, or if the following events that run under that hat should be denied altogether. .SS "Capability Events" .IX Subsection "Capability Events" If there are capability accesses, the user is shown each capability access and asked if the capability should be allowed, denied, or if the user wants to quit. See \fIcapability\fR\|(7) for details. .SH "BUGS" .IX Header "BUGS" If you find any bugs, please report them at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIklogd\fR\|(8), \fIauditd\fR\|(8), \fIapparmor\fR\|(7), \fIapparmor.d\fR\|(5), \fIaa_change_hat\fR\|(2), \&\fIlogprof.conf\fR\|(5), \fIaa\-genprof\fR\|(1), \fIaa\-enforce\fR\|(1), \fIaa\-complain\fR\|(1), \&\fIaa\-disable\fR\|(1), and . apparmor-2.13.3/common/0000755000175000017500000000000013502024371012476 5ustar jjjjapparmor-2.13.3/common/.stamp_rev0000644000175000017500000000012013502024371014470 0ustar jjjjgit@gitlab.com:apparmor/apparmor.git apparmor-2.13 v2.13.2-89-g2f9d9ea7e01a115b apparmor-2.13.3/common/Make-po.rules0000644000175000017500000000356313502024172015051 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (c) 1999-2008 NOVELL (All rights reserved) # Copyright 2009-2015 Canonical Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # ------------------------------------------------------------------ # # The including makefile needs to define LANG, which lists the lang # files to include; e.g. LANG=en_US de_DE, where en_US.po and de_DE.po # exist LOCALEDIR=/usr/share/locale XGETTEXT_ARGS=--copyright-holder="Canonical Ltd" --msgid-bugs-address=apparmor@lists.ubuntu.com -d ${NAME} # When making the .pot file, it's expected that the parent Makefile will # pass in the list of sources in the SOURCES variable PARENT_SOURCES=$(foreach source, ${SOURCES}, ../${source}) # Can override by passing LANGS=whatever here LANGS?=$(patsubst %.po, %, $(wildcard *.po)) TARGET_MOS=$(foreach lang, $(filter-out $(DISABLED_LANGS),$(LANGS)), ${lang}.mo) .PHONY: all all: ${TARGET_MOS} ${NAME}.pot: ${PARENT_SOURCES} xgettext ${XGETTEXT_ARGS} ${PARENT_SOURCES} -o $@ %.mo: %.po msgfmt -c -o $@ $< .PHONY: install install: ${TARGET_MOS} mkdir -p $(DESTDIR)/${LOCALEDIR} for lang in ${LANGS} ; do \ mkdir -p ${DESTDIR}/${LOCALEDIR}/$${lang}/LC_MESSAGES ; \ install -m 644 $${lang}.mo ${DESTDIR}/${LOCALEDIR}/$${lang}/LC_MESSAGES/${NAME}.mo ; \ done .PHONY: clean clean: rm -f *.mo Make.rules apparmor-2.13.3/common/Version0000644000175000017500000000000713502024172014042 0ustar jjjj2.13.3 apparmor-2.13.3/common/apparmor.css0000644000175000017500000000175413502024172015037 0ustar jjjjBODY {background:rgb(000,000,000); color:rgb(225,225,225); margin-left: 1%; margin-right: 5%} H1 {color:rgb(240,240,240); font-size:115%;} H2 {color:rgb(240,240,240); font-size:109%;} H3 {color:rgb(240,240,240); font-size:104%;} TD.sidebar {width:18em; background:rgb(020,020,020); vertical-align:top;} TD.main {width:250em; background:rgb(020,020,020); padding-top:5px; padding-bottom:5px; padding-left:10px; padding-right:10px; } TD.sidebarhead {background:rgb(038,038,038);} TD.footer {background:rgb(020,020,020); padding:5px; } TD.block {background: #9c9c9c; color:rgb(000,000,000)} P {font-size:102%} P {margin-left:.5em; margin-right:.5em} P {color:rgb(225,225,225)} P.sidebar {font-size:98% } P.sidebarhead {font-size:98%; font-weight:bold; } UL {font-size:102%} UL {margin-left:.5em; margin-right:.5em} UL {color:rgb(225,225,225)} IMG {border:none} :link, :visited, :active { text-decoration:underline; } :link { color: white } :visited { color: rgb(225,225,225)} :active { color: gray } apparmor-2.13.3/common/Make.rules0000644000175000017500000001273713502024172014440 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2002-2005 Novell/SUSE # Copyright (C) 2010-2015 Canonical, Ltd. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Novell, Inc. # ------------------------------------------------------------------ # Make.rules - common make targets and variables for building AppArmor # # NOTES: # Before including this file in your Makefile, you should # - define COMMONDIR (the location of the common/ directory) # - define the default rule (usually 'all:'). (Note: you can redefine # it later in your Makefile) .PHONY: common_Make.rules_is_a_bad_target common_Make.rules_is_a_bad_target: @echo "*** default target in common/Make.rules hit - either you did something strange, or something is broken... ***" exit 1 DISTRIBUTION=AppArmor VERSION=$(shell cat $(COMMONDIR)/Version) # Convenience functions pathsearch = $(firstword $(wildcard $(addsuffix /$(1),$(subst :, ,$(PATH))))) map = $(foreach a,$(2),$(call $(1),$(a))) AWK:=$(shell which awk) ifndef AWK $(error awk utility required for build but not available) endif define nl endef REPO_VERSION_CMD=[ -x /usr/bin/git ] && /usr/bin/git describe --tags --long --abbrev=16 --match 'v*' 2> /dev/null || awk '{ print $2 }' common/.stamp_rev ifndef PYTHON_VERSIONS PYTHON_VERSIONS = $(call map, pathsearch, python2 python3) endif ifndef PYTHON PYTHON = $(firstword ${PYTHON_VERSIONS}) endif #Helper function to be used with $(call pyalldo, run_test_with_all.py) pyalldo=set -e; $(foreach py, $(PYTHON_VERSIONS), $(py) $(1);) .PHONY: version .SILENT: version version: echo $(VERSION) .PHONY: repo_version .SILENT: repo_version repo_version: echo $(shell $(value REPO_VERSION_CMD)) .PHONY: pod_clean ifndef VERBOSE .SILENT: pod_clean endif pod_clean: -rm -f ${MANPAGES} *.[0-9].gz ${HTMLMANPAGES} pod2htm*.tmp # ===================== # generate list of capabilities based on # /usr/include/linux/capabilities.h for use in multiple locations in # the source tree # ===================== # emits defined capabilities in a simple list, e.g. "CAP_NAME CAP_NAME2" CAPABILITIES=$(shell echo "\#include " | cpp -dM | LC_ALL=C sed -n -e '/CAP_EMPTY_SET/d' -e 's/^\#define[ \t]\+CAP_\([A-Z0-9_]\+\)[ \t]\+\([0-9xa-f]\+\)\(.*\)$$/CAP_\1/p' | LC_ALL=C sort) .PHONY: list_capabilities list_capabilities: /usr/include/linux/capability.h @echo "$(CAPABILITIES)" # ===================== # generate list of network protocols based on # sys/socket.h for use in multiple locations in # the source tree # ===================== # These are the families that it doesn't make sense for apparmor # to mediate. We use PF_ here since that is what is required in # bits/socket.h, but we will rewrite these as AF_. FILTER_FAMILIES=PF_UNIX __FILTER=$(shell echo $(strip $(FILTER_FAMILIES)) | sed -e 's/ /\\\|/g') # emits the AF names in a "AF_NAME NUMBER," pattern AF_NAMES=$(shell echo "\#include " | cpp -dM | LC_ALL=C sed -n -e '/$(__FILTER)/d' -e 's/PF_LOCAL/PF_UNIX/' -e 's/^\#define[ \t]\+PF_\([A-Z0-9_]\+\)[ \t]\+\([0-9]\+\).*$$/AF_\1 \2,/p' | sort -n -k2) .PHONY: list_af_names list_af_names: @echo "$(AF_NAMES)" # ===================== # manpages # ===================== POD2MAN = /usr/bin/pod2man POD2HTML = /usr/bin/pod2html MANDIR = /usr/share/man DOCDIR = /usr/share/doc/${NAME}-${VERSION} # get list of directory numbers based on definition of MANPAGES variable MANDIRS=$(sort $(foreach dir, 1 2 3 4 5 6 7 8, $(patsubst %.${dir}, ${dir}, $(filter %.${dir}, ${MANPAGES})))) HTMLMANPAGES=$(foreach manpage, ${MANPAGES}, ${manpage}.html) .PHONY: install_manpages install_manpages: $(MANPAGES) $(foreach dir, ${MANDIRS}, \ install -d ${DESTDIR}/${MANDIR}/man${dir} ; \ install -m 644 $(filter %.${dir}, ${MANPAGES}) ${DESTDIR}/${MANDIR}/man${dir}; \ ) MAN_RELEASE="AppArmor ${VERSION}" %.1 %.2 %.3 %.4 %.5 %.6 %.7 %.8: %.pod $(POD2MAN) $< --release=$(MAN_RELEASE) --center=AppArmor --stderr --section=$(subst .,,$(suffix $@)) > $@ %.1.html: %.pod $(POD2HTML) --header --css apparmor.css --infile=$< --outfile=$@ %.2.html: %.pod $(POD2HTML) --header --css apparmor.css --infile=$< --outfile=$@ %.3.html: %.pod $(POD2HTML) --header --css apparmor.css --infile=$< --outfile=$@ %.4.html: %.pod $(POD2HTML) --header --css apparmor.css --infile=$< --outfile=$@ %.5.html: %.pod $(POD2HTML) --header --css apparmor.css --infile=$< --outfile=$@ %.6.html: %.pod $(POD2HTML) --header --css apparmor.css --infile=$< --outfile=$@ %.7.html: %.pod $(POD2HTML) --header --css apparmor.css --infile=$< --outfile=$@ %.8.html: %.pod $(POD2HTML) --header --css apparmor.css --infile=$< --outfile=$@ A2PS_ARGS=-Ec -g --line-numbers=1 ENSCRIPT_ARGS=-C -2jGr -f Courier6 -E %.c.ps: %.c #a2ps ${A2PS_ARGS} $< -o $@ enscript ${ENSCRIPT_ARGS} -o $@ $< %.pm.ps: %.pm enscript ${ENSCRIPT_ARGS} -o $@ $< .PHONY: check_pod_files check_pod_files: LANG=C podchecker -warning -warning *.pod apparmor-2.13.3/parser/0000755000175000017500000000000013502024374012505 5ustar jjjjapparmor-2.13.3/parser/techdoc.out0000644000175000017500000000417413502024374014655 0ustar jjjj\BOOKMARK [1][-]{section.1}{Introduction}{}% 1 \BOOKMARK [1][-]{section.2}{Overview}{}% 2 \BOOKMARK [1][-]{section.3}{The AppArmor Security Model}{}% 3 \BOOKMARK [2][-]{subsection.3.1}{Symbolic Links}{section.3}% 4 \BOOKMARK [2][-]{subsection.3.2}{Namespaces}{section.3}% 5 \BOOKMARK [2][-]{subsection.3.3}{Disconnected Files and Pseudo File Systems}{section.3}% 6 \BOOKMARK [2][-]{subsection.3.4}{Mount}{section.3}% 7 \BOOKMARK [2][-]{subsection.3.5}{The Kernel NFS Daemon}{section.3}% 8 \BOOKMARK [2][-]{subsection.3.6}{Why are the computed pathnames meaningful?}{section.3}% 9 \BOOKMARK [2][-]{subsection.3.7}{Path Permission Checking}{section.3}% 10 \BOOKMARK [2][-]{subsection.3.8}{Profile Permissions}{section.3}% 11 \BOOKMARK [2][-]{subsection.3.9}{System Calls Taking File Handles, At System Calls}{section.3}% 12 \BOOKMARK [2][-]{subsection.3.10}{File Descriptor Passing and Revalidation}{section.3}% 13 \BOOKMARK [2][-]{subsection.3.11}{Deleted Files}{section.3}% 14 \BOOKMARK [2][-]{subsection.3.12}{The access System Call}{section.3}% 15 \BOOKMARK [2][-]{subsection.3.13}{The ptrace System Call}{section.3}% 16 \BOOKMARK [2][-]{subsection.3.14}{Secure Execution}{section.3}% 17 \BOOKMARK [2][-]{subsection.3.15}{Exec Mode Merging in Profiles, Exact Matches}{section.3}% 18 \BOOKMARK [2][-]{subsection.3.16}{Capabilities}{section.3}% 19 \BOOKMARK [2][-]{subsection.3.17}{The sysctl System Call and /proc/sys}{section.3}% 20 \BOOKMARK [2][-]{subsection.3.18}{Subprofiles aka. Hats}{section.3}% 21 \BOOKMARK [2][-]{subsection.3.19}{Association of Profiles with Processes}{section.3}% 22 \BOOKMARK [2][-]{subsection.3.20}{Profile Loading, Replacement, and Removal}{section.3}% 23 \BOOKMARK [1][-]{section.4}{AppArmor Walk-Through}{}% 24 \BOOKMARK [2][-]{subsection.4.1}{Kernel Patches and Configuration}{section.4}% 25 \BOOKMARK [2][-]{subsection.4.2}{The securityfs file system}{section.4}% 26 \BOOKMARK [2][-]{subsection.4.3}{Profile Loading}{section.4}% 27 \BOOKMARK [2][-]{subsection.4.4}{Anatomy of a Profile}{section.4}% 28 \BOOKMARK [2][-]{subsection.4.5}{Logging}{section.4}% 29 \BOOKMARK [2][-]{subsection.4.6}{Generating Profiles By Hand}{section.4}% 30 apparmor-2.13.3/parser/apparmor.d.5.html0000644000175000017500000021514613502024374015612 0ustar jjjj
 

NAME

apparmor.d - syntax of security profiles for AppArmor.

DESCRIPTION

AppArmor profiles describe mandatory access rights granted to given programs and are fed to the AppArmor policy enforcement module using apparmor_parser(8). This man page describes the format of the AppArmor configuration files; see apparmor(7) for an overview of AppArmor.

FORMAT

The following is a BNF-style description of AppArmor policy configuration files; see below for an example AppArmor policy file. AppArmor configuration files are line-oriented; # introduces a comment, similar to shell scripting languages. The exception to this rule is that #include will include the contents of a file inline to the policy; this behaviour is modelled after cpp(1).

    PROFILE FILE = ( [ PREAMBLE ] [ PROFILE ] )*

    PREAMBLE = ( COMMENT | VARIABLE ASSIGNMENT | ALIAS RULE | INCLUDE )* Variable assignment and alias rules must come before the profile.

    VARIABLE ASSIGNMENT = VARIABLE ('=' | '+=') (space separated values)

    VARIABLE = '@{' ALPHA [ ( ALPHANUMERIC | '_' ) ... ] '}'

    ALIAS RULE = 'alias' ABS PATH '->' REWRITTEN ABS PATH ','

    INCLUDE = ( '#include' | 'include' ) [ 'if exists' ] ( ABS PATH | MAGIC PATH )

    ABS PATH = '"' path '"' (the path is passed to open(2))

    MAGIC PATH = '<' relative path '>' The path is relative to /etc/apparmor.d/.

    COMMENT = '#' TEXT [ '\r' ] '\n'

    TEXT = any characters

    PROFILE = ( PROFILE HEAD ) [ ATTACHMENT SPECIFICATION ] [ PROFILE FLAG CONDS ] '{' ( RULES )* '}'

    PROFILE HEAD = [ 'profile' ] FILEGLOB | 'profile' PROFILE NAME

    PROFILE NAME ( UNQUOTED PROFILE NAME | QUOTED PROFILE NAME )

    QUOTED PROFILE NAME = '"' UNQUOTED PROFILE NAME '"'

    UNQUOTED PROFILE NAME = (must start with alphanumeric character (after variable expansion), or '/' AARE have special meanings; see below. May include VARIABLE. Rules with embedded spaces or tabs must be quoted.)

    ATTACHMENT SPECIFICATION = FILEGLOB

    PROFILE FLAG CONDS = [ 'flags=' ] '(' comma or white space separated list of PROFILE FLAGS ')'

    PROFILE FLAGS = 'complain' | 'audit' | 'enforce' | 'mediate_deleted' | 'attach_disconnected' | 'chroot_relative'

    RULES = [ ( LINE RULES | COMMA RULES ',' | BLOCK RULES )

    LINE RULES = ( COMMENT | INCLUDE ) [ '\r' ] '\n'

    COMMA RULES = ( CAPABILITY RULE | NETWORK RULE | MOUNT RULE | PIVOT ROOT RULE | UNIX RULE | FILE RULE | LINK RULE | CHANGE_PROFILE RULE | RLIMIT RULE | DBUS RULE )

    BLOCK RULES = ( SUBPROFILE | HAT | QUALIFIER BLOCK )

    SUBPROFILE = 'profile' PROFILE NAME [ ATTACHMENT SPECIFICATION ] [ PROFILE FLAG CONDS ] '{' ( RULES )* '}'

    HAT = ('hat' | '^') HATNAME [ PROFILE FLAG CONDS ] '{' ( RULES )* '}'

    HATNAME = (must start with alphanumeric character. See aa_change_hat(2) for a description of how this "hat" is used. If '^' is used to start a hat then there is no space between the '^' and HATNAME)

    QUALIFIER BLOCK = QUALIFIERS BLOCK

    ACCESS TYPE = ( 'allow' | 'deny' )

    QUALIFIERS = [ 'audit' ] [ ACCESS TYPE ]

    CAPABILITY RULE = [ QUALIFIERS ] 'capability' [ CAPABILITY LIST ]

    CAPABILITY LIST = ( CAPABILITY )+

    CAPABILITY = (lowercase capability name without 'CAP_' prefix; see capabilities(7))

    NETWORK RULE = [ QUALIFIERS ] 'network' [ DOMAIN ] [ TYPE | PROTOCOL ]

    DOMAIN = ( 'unix' | 'inet' | 'ax25' | 'ipx' | 'appletalk' | 'netrom' | 'bridge' | 'atmpvc' | 'x25' | 'inet6' | 'rose' | 'netbeui' | 'security' | 'key' | 'netlink' | 'packet' | 'ash' | 'econet' | 'atmsvc' | 'rds' | 'sna' | 'irda' | 'pppox' | 'wanpipe' | 'llc' | 'ib' | 'mpls' | 'can' | 'tipc' | 'bluetooth' | 'iucv' | 'rxrpc' | 'isdn' | 'phonet' | 'ieee802154' | 'caif' | 'alg' | 'nfc' | 'vsock' | 'kcm' | 'qipcrtr' | 'smc' | 'xdp' ) ','

    TYPE = ( 'stream' | 'dgram' | 'seqpacket' | 'rdm' | 'raw' | 'packet' )

    PROTOCOL = ( 'tcp' | 'udp' | 'icmp' )

    MOUNT RULE = ( MOUNT | REMOUNT | UMOUNT )

    MOUNT = [ QUALIFIERS ] 'mount' [ MOUNT CONDITIONS ] [ SOURCE FILEGLOB ] [ '->' [ MOUNTPOINT FILEGLOB ]

    REMOUNT = [ QUALIFIERS ] 'remount' [ MOUNT CONDITIONS ] MOUNTPOINT FILEGLOB

    UMOUNT = [ QUALIFIERS ] 'umount' [ MOUNT CONDITIONS ] MOUNTPOINT FILEGLOB

    MOUNT CONDITIONS = [ ( 'fstype' | 'vfstype' ) ( '=' | 'in' ) MOUNT FSTYPE EXPRESSION ] [ 'options' ( '=' | 'in' ) MOUNT FLAGS EXPRESSION ]

    MOUNT FSTYPE EXPRESSION = ( MOUNT FSTYPE LIST | MOUNT EXPRESSION )

    MOUNT FSTYPE LIST = Comma separated list of valid filesystem and virtual filesystem types (eg ext4, debugfs, devfs, etc)

    MOUNT FLAGS EXPRESSION = ( MOUNT FLAGS LIST | MOUNT EXPRESSION )

    MOUNT FLAGS LIST = Comma separated list of MOUNT FLAGS.

    MOUNT FLAGS = ( 'ro' | 'rw' | 'nosuid' | 'suid' | 'nodev' | 'dev' | 'noexec' | 'exec' | 'sync' | 'async' | 'remount' | 'mand' | 'nomand' | 'dirsync' | 'noatime' | 'atime' | 'nodiratime' | 'diratime' | 'bind' | 'rbind' | 'move' | 'verbose' | 'silent' | 'loud' | 'acl' | 'noacl' | 'unbindable' | 'runbindable' | 'private' | 'rprivate' | 'slave' | 'rslave' | 'shared' | 'rshared' | 'relatime' | 'norelatime' | 'iversion' | 'noiversion' | 'strictatime' | 'nouser' | 'user' )

    MOUNT EXPRESSION = ( ALPHANUMERIC | AARE ) ...

    PIVOT ROOT RULE = [ QUALIFIERS ] pivot_root [ oldroot=OLD PUT FILEGLOB ] [ NEW ROOT FILEGLOB ] [ '->' PROFILE NAME ]

    SOURCE FILEGLOB = FILEGLOB

    MOUNTPOINT FILEGLOB = FILEGLOB

    OLD PUT FILEGLOB = FILEGLOB

    PTRACE_RULE = [ QUALIFIERS ] 'ptrace' [ PTRACE ACCESS PERMISSIONS ] [ PTRACE PEER ]

    PTRACE ACCESS PERMISSIONS = PTRACE ACCESS | PTRACE ACCESS LIST

    PTRACE ACCESS LIST = '(' Comma or space separated list of PTRACE ACCESS ')'

    PTRACE ACCESS = ( 'r' | 'w' | 'rw' | 'read' | 'readby' | 'trace' | 'tracedby' )

    PTRACE PEER = 'peer' '=' AARE

    SIGNAL_RULE = [ QUALIFIERS ] 'signal' [ SIGNAL ACCESS PERMISSIONS ] [ SIGNAL SET ] [ SIGNAL PEER ]

    SIGNAL ACCESS PERMISSIONS = SIGNAL ACCESS | SIGNAL ACCESS LIST

    SIGNAL ACCESS LIST = '(' Comma or space separated list of SIGNAL ACCESS ')'

    SIGNAL ACCESS = ( 'r' | 'w' | 'rw' | 'read' | 'write' | 'send' | 'receive' )

    SIGNAL SET = 'set' '=' '(' SIGNAL LIST ')'

    SIGNAL LIST = Comma or space separated list of SIGNALS

    SIGNALS = ( 'hup' | 'int' | 'quit' | 'ill' | 'trap' | 'abrt' | 'bus' | 'fpe' | 'kill' | 'usr1' | 'segv' | 'usr2' | 'pipe' | 'alrm' | 'term' | 'stkflt' | 'chld' | 'cont' | 'stop' | 'stp' | 'ttin' | 'ttou' | 'urg' | 'xcpu' | 'xfsz' | 'vtalrm' | 'prof' | 'winch' | 'io' | 'pwr' | 'sys' | 'emt' | 'exists' | 'rtmin+0' ... 'rtmin+32' )

    SIGNAL PEER = 'peer' '=' AARE

    DBUS RULE = ( DBUS MESSAGE RULE | DBUS SERVICE RULE | DBUS EAVESDROP RULE | DBUS COMBINED RULE )

    DBUS MESSAGE RULE = [ QUALIFIERS ] 'dbus' [ DBUS ACCESS EXPRESSION ] [ DBUS BUS ] [ DBUS PATH ] [ DBUS INTERFACE ] [ DBUS MEMBER ] [ DBUS PEER ]

    DBUS SERVICE RULE = [ QUALIFIERS ] 'dbus' [ DBUS ACCESS EXPRESSION ] [ DBUS BUS ] [ DBUS NAME ]

    DBUS EAVESDROP RULE = [ QUALIFIERS ] 'dbus' [ DBUS ACCESS EXPRESSION ] [ DBUS BUS ]

    DBUS COMBINED RULE = [ QUALIFIERS ] 'dbus' [ DBUS ACCESS EXPRESSION ] [ DBUS BUS ]

    DBUS ACCESS EXPRESSION = ( DBUS ACCESS | '(' DBUS ACCESS LIST ')' )

    DBUS BUS = 'bus' '=' '(' 'system' | 'session' | '"' AARE '"' | AARE ')'

    DBUS PATH = 'path' '=' '(' '"' AARE '"' | AARE ')'

    DBUS INTERFACE = 'interface' '=' '(' '"' AARE '"' | AARE ')'

    DBUS MEMBER = 'member' '=' '(' '"' AARE '"' | AARE ')'

    DBUS PEER = 'peer' '=' '(' [ DBUS NAME ] [ DBUS LABEL ] ')'

    DBUS NAME = 'name' '=' '(' '"' AARE '"' | AARE ')'

    DBUS LABEL = 'label' '=' '(' '"' AARE '"' | AARE ')'

    DBUS ACCESS LIST = Comma separated list of DBUS ACCESS

    DBUS ACCESS = ( 'send' | 'receive' | 'bind' | 'eavesdrop' | 'r' | 'read' | 'w' | 'write' | 'rw' ) Some accesses are incompatible with some rules; see below.

    AARE = ?*[]{}^ See below for meanings.

    UNIX RULE = [ QUALIFIERS ] 'unix' [ UNIX ACCESS EXPR ] [ UNIX RULE CONDS ] [ UNIX LOCAL EXPR ] [ UNIX PEER EXPR ]

    UNIX ACCESS EXPR = ( UNIX ACCESS | UNIX ACCESS LIST )

    UNIX ACCESS = ( 'create' | 'bind' | 'listen' | 'accept' | 'connect' | 'shutdown' | 'getattr' | 'setattr' | 'getopt' | 'setopt' | 'send' | 'receive' | 'r' | 'w' | 'rw' ) Some access modes are incompatible with some rules or require additional parameters.

    UNIX ACCESS LIST = '(' UNIX ACCESS ( [','] UNIX ACCESS )* ')'

    UNIX RULE CONDS = ( TYPE COND | PROTO COND ) Each cond can appear at most once.

    TYPE COND = 'type' '=' ( AARE | '(' ( '"' AARE '"' | AARE )+ ')' )

    PROTO COND = 'protocol' '=' ( AARE | '(' ( '"' AARE '"' | AARE )+ ')' )

    UNIX LOCAL EXPR = ( UNIX ADDRESS COND | UNIX LABEL COND | UNIX ATTR COND | UNIX OPT COND )* Each cond can appear at most once.

    UNIX PEER EXPR = 'peer' '=' ( UNIX ADDRESS COND | UNIX LABEL COND )+ Each cond can appear at most once.

    UNIX ADDRESS COND 'addr' '=' ( AARE | '(' '"' AARE '"' | AARE ')' )

    UNIX LABEL COND 'label' '=' ( AARE | '(' '"' AARE '"' | AARE ')' )

    UNIX ATTR COND 'attr' '=' ( AARE | '(' '"' AARE '"' | AARE ')' )

    UNIX OPT COND 'opt' '=' ( AARE | '(' '"' AARE '"' | AARE ')' )

    RLIMIT RULE = 'set' 'rlimit' [RLIMIT '<=' RLIMIT VALUE ]

    RLIMIT = ( 'cpu' | 'fsize' | 'data' | 'stack' | 'core' | 'rss' | 'nofile' | 'ofile' | 'as' | 'nproc' | 'memlock' | 'locks' | 'sigpending' | 'msgqueue' | 'nice' | 'rtprio' | 'rttime' )

    RLIMIT VALUE = ( RLIMIT SIZE | RLIMIT NUMBER | RLIMIT TIME | RLIMIT NICE )

    RLIMIT SIZE = NUMBER ( 'K' | 'M' | 'G' ) Only applies to RLIMIT of 'fsize', 'data', 'stack', 'core', 'rss', 'as', 'memlock', 'msgqueue'.

    RLIMIT NUMBER = number from 0 to max rlimit value. Only applies to RLIMIT of 'ofile', 'nofile', 'locks', 'sigpending', 'nproc', 'rtprio'.

    RLIMIT TIME = NUMBER ( 'us' | 'microsecond' | 'microseconds' | 'ms' | 'millisecond' | 'milliseconds' | 's' | 'sec' | 'second' | 'seconds' | 'min' | 'minute' | 'minutes' | 'h' | 'hour' | 'hours' | 'd' | 'day' | 'days' | 'week' | 'weeks' ) Only applies to RLIMIT of 'cpu' and 'rttime'. RLIMIT 'cpu' only allows units >= 'seconds'.

    RLIMIT NICE = a number between -20 and 19. Only applies to RLIMIT of 'nice'.

    FILE RULE = [ QUALIFIERS ] [ 'owner' ] ( 'file' | [ 'file' ] ( FILEGLOB ACCESS | ACCESS FILEGLOB ) [ '->' EXEC TARGET ] )

    FILEGLOB = ( QUOTED FILEGLOB | UNQUOTED FILEGLOB )

    QUOTED FILEGLOB = '"' UNQUOTED FILEGLOB '"'

    UNQUOTED FILEGLOB = (must start with '/' (after variable expansion), AARE have special meanings; see below. May include VARIABLE. Rules with embedded spaces or tabs must be quoted. Rules must end with '/' to apply to directories.)

    ACCESS = ( 'r' | 'w' | 'a' | 'l' | 'k' | 'm' | EXEC TRANSITION )+ (not all combinations are allowed; see below.)

    EXEC TRANSITION = ( 'ix' | 'ux' | 'Ux' | 'px' | 'Px' | 'cx' | 'Cx' | 'pix' | 'Pix' | 'cix' | 'Cix' | 'pux' | 'PUx' | 'cux' | 'CUx' | 'x' ) A bare 'x' is only allowed in rules with the deny qualifier, everything else only without the deny qualifier.

    EXEC TARGET = name Requires EXEC TRANSITION specified.

    LINK RULE = QUALIFIERS [ 'owner' ] 'link' [ 'subset' ] FILEGLOB '->' FILEGLOB

    ALPHA = ('a', 'b', 'c', ... 'z', 'A', 'B', ... 'Z')

    ALPHANUMERIC = ('0', '1', '2', ... '9', 'a', 'b', 'c', ... 'z', 'A', 'B', ... 'Z')

    CHANGE_PROFILE RULE = 'change_profile' [ [ EXEC MODE ] EXEC COND ] [ '->' PROFILE NAME ]

    EXEC_MODE = ( 'safe' | 'unsafe' )

    EXEC COND = FILEGLOB

All resources and programs need a full path. There may be any number of subprofiles (aka child profiles) in a profile, limited only by kernel memory. Subprofile names are limited to 974 characters. Child profiles can be used to confine an application in a special way, or when you want the child to be unconfined on the system, but confined when called from the parent. Hats are a special child profile that can be used with the aa_change_hat(2) API call. Applications written or modified to use aa_change_hat(2) can take advantage of subprofiles to run under different confinements, dependent on program logic. Several aa_change_hat(2)-aware applications exist, including an Apache module, mod_apparmor(5); a PAM module, pam_apparmor; and a Tomcat valve, tomcat_apparmor. Applications written or modified to use change_profile(2) transition permanently to the specified profile. libvirt is one such application.

Access Modes

File permission access modes consists of combinations of the following modes:

r

- read

w

- write -- conflicts with append

a

- append -- conflicts with write

ux

- unconfined execute

Ux

- unconfined execute -- scrub the environment

px

- discrete profile execute

Px

- discrete profile execute -- scrub the environment

cx

- transition to subprofile on execute

Cx

- transition to subprofile on execute -- scrub the environment

ix

- inherit execute

pix

- discrete profile execute with inherit fallback

Pix

- discrete profile execute with inherit fallback -- scrub the environment

cix

- transition to subprofile on execute with inherit fallback

Cix

- transition to subprofile on execute with inherit fallback -- scrub the environment

pux

- discrete profile execute with fallback to unconfined

PUx

- discrete profile execute with fallback to unconfined -- scrub the environment

cux

- transition to subprofile on execute with fallback to unconfined

CUx

- transition to subprofile on execute with fallback to unconfined -- scrub the environment

deny x

- disallow execute (in rules with the deny qualifier)

m

- allow PROT_EXEC with mmap(2) calls

l

- link

k

- lock

Access Modes Details

r - Read mode

Allows the program to have read access to the file or directory listing. Read access is required for shell scripts and other interpreted content.

w - Write mode

Allows the program to have write access to the file. Files and directories must have this permission if they are to be unlinked (removed.) Write mode is not required on a directory to rename or create files within the directory.

This mode conflicts with append mode.

a - Append mode

Allows the program to have a limited appending only write access to the file. Append mode will prevent an application from opening the file for write unless it passes the O_APPEND parameter flag on open.

The mode conflicts with Write mode.

ux - Unconfined execute mode

Allows the program to execute the program without any AppArmor profile being applied to the program.

This mode is useful when a confined program needs to be able to perform a privileged operation, such as rebooting the machine. By placing the privileged section in another executable and granting unconfined execution rights, it is possible to bypass the mandatory constraints imposed on all confined processes. For more information on what is constrained, see the apparmor(7) man page.

WARNING 'ux' should only be used in very special cases. It enables the designated child processes to be run without any AppArmor protection. 'ux' does not scrub the environment of variables such as LD_PRELOAD; as a result, the calling domain may have an undue amount of influence over the callee. Use this mode only if the child absolutely must be run unconfined and LD_PRELOAD must be used. Any profile using this mode provides negligible security. Use at your own risk.

Incompatible with other exec transition modes and the deny qualifier.

Ux - unconfined execute -- scrub the environment

'Ux' allows the named program to run in 'ux' mode, but AppArmor will invoke the Linux Kernel's unsafe_exec routines to scrub the environment, similar to setuid programs. (See ld.so(8) for some information on setuid/setgid environment scrubbing.)

WARNING 'Ux' should only be used in very special cases. It enables the designated child processes to be run without any AppArmor protection. Use this mode only if the child absolutely must be run unconfined. Use at your own risk.

Incompatible with other exec transition modes and the deny qualifier.

px - Discrete Profile execute mode

This mode requires that a discrete security profile is defined for a program executed and forces an AppArmor domain transition. If there is no profile defined then the access will be denied.

WARNING 'px' does not scrub the environment of variables such as LD_PRELOAD; as a result, the calling domain may have an undue amount of influence over the callee.

Incompatible with other exec transition modes and the deny qualifier.

Px - Discrete Profile execute mode -- scrub the environment

'Px' allows the named program to run in 'px' mode, but AppArmor will invoke the Linux Kernel's unsafe_exec routines to scrub the environment, similar to setuid programs. (See ld.so(8) for some information on setuid/setgid environment scrubbing.)

Incompatible with other exec transition modes and the deny qualifier.

cx - Transition to Subprofile execute mode

This mode requires that a local security profile is defined and forces an AppArmor domain transition to the named profile. If there is no profile defined then the access will be denied.

WARNING 'cx' does not scrub the environment of variables such as LD_PRELOAD; as a result, the calling domain may have an undue amount of influence over the callee.

Incompatible with other exec transition modes and the deny qualifier.

Cx - Transition to Subprofile execute mode -- scrub the environment

'Cx' allows the named program to run in 'cx' mode, but AppArmor will invoke the Linux Kernel's unsafe_exec routines to scrub the environment, similar to setuid programs. (See ld.so(8) for some information on setuid/setgid environment scrubbing.)

Incompatible with other exec transition modes and the deny qualifier.

ix - Inherit execute mode

Prevent the normal AppArmor domain transition on execve(2) when the profiled program executes the named program. Instead, the executed resource will inherit the current profile.

This mode is useful when a confined program needs to call another confined program without gaining the permissions of the target's profile, or losing the permissions of the current profile. There is no version to scrub the environment because 'ix' executions don't change privileges.

Incompatible with other exec transition modes and the deny qualifier.

Profile transition with inheritance fallback execute mode

These modes attempt to perform a domain transition as specified by the matching permission (shown below) and if that transition fails to find the matching profile the domain transition proceeds using the 'ix' transition mode.

  'Pix' == 'Px' with fallback to 'ix'
  'pix' == 'px' with fallback to 'ix'
  'Cix' == 'Cx' with fallback to 'ix'
  'cix' == 'cx' with fallback to 'ix'

Incompatible with other exec transition modes and the deny qualifier.

Profile transition with unconfined fallback execute mode

These modes attempt to perform a domain transition as specified by the matching permission (shown below) and if that transition fails to find the matching profile the domain transition proceeds using the 'ux' transition mode if 'pux', 'cux' or the 'Ux' transition mode if 'PUx', 'CUx' is used.

  'PUx' == 'Px' with fallback to 'Ux'
  'pux' == 'px' with fallback to 'ux'
  'CUx' == 'Cx' with fallback to 'Ux'
  'cux' == 'cx' with fallback to 'ux'

Incompatible with other exec transition modes and the deny qualifier.

deny x - Deny execute

For rules including the deny modifier, only 'x' is allowed to deny execute.

The 'ix', 'Px', 'px', 'Cx', 'cx' and the fallback modes conflict with the deny modifier.

Directed profile transitions

The directed ('px', 'Px', 'pix', 'Pix', 'pux', 'PUx') profile and subprofile ('cx', 'Cx', 'cix', 'Cix', 'cux', 'CUx') transitions normally determine the profile to transition to from the executable name. It is however possible to specify the name of the profile that the transition should use.

The name of the profile to transition to is specified using the '->' followed by the name of the profile to transition to. Eg.

  /bin/** px -> profile,

Incompatible with other exec transition modes.

m - Allow executable mapping

This mode allows a file to be mapped into memory using mmap(2)'s PROT_EXEC flag. This flag marks the pages executable; it is used on some architectures to provide non-executable data pages, which can complicate exploit attempts. AppArmor uses this mode to limit which files a well-behaved program (or all programs on architectures that enforce non-executable memory access controls) may use as libraries, to limit the effect of invalid -L flags given to ld(1) and LD_PRELOAD, LD_LIBRARY_PATH, given to ld.so(8).

Allows the program to be able to create a link with this name. When a link is created, the new link MUST have a subset of permissions as the original file (with the exception that the destination does not have to have link access.) If there is an 'x' rule on the new link, it must match the original file exactly.

k - lock mode

Allows the program to be able lock a file with this name. This permission covers both advisory and mandatory locking.

leading OR trailing access permissions

File rules can be specified with the access permission either leading or trailing the file glob. Eg.

  rw /**,               # leading permissions

  /** rw,               # trailing permissions

When leading permissions are used further rule options and context may be allowed, Eg.

  l /foo -> /bar,       # lead 'l' link permission is equivalent to link rules

Link rules allow specifying permission to form a hard link as a link target pair. If the subset condition is specified then the permissions to access the link file must be a subset of the profiles permissions to access the target file. If there is an 'x' rule on the new link, it must match the original file exactly.

Eg.

  /file1  r,
  /file2  rwk,
  /link*  rw,
  link subset /link* -> /**,

The link rule allows linking of /link to both /file1 or /file2 by name however because the /link file has 'rw' permissions it is not allowed to link to /file1 because that would grant an access path to /file1 with more permissions than the 'r' permissions the profile specifies.

A link of /link to /file2 would be allowed because the 'rw' permissions of /link are a subset of the 'rwk' permissions for /file1.

The link rule is equivalent to specifying the 'l' link permission as a leading permission with no other file access permissions. When this is done the link rule options can be specified.

The following link rule is equivalent to the 'l' permission file rule

  link /foo -> bar,
  l /foo -> /bar,

File rules that specify the 'l' permission and don't specify the extend link permissions map to link rules as follows.

  /foo l,
  l /foo,
  link subset /foo -> /**,

Comments

Comments start with # and may begin at any place within a line. The comment ends when the line ends. This is the same comment style as shell scripts.

Capabilities

The only capabilities a confined process may use may be enumerated; for the complete list, please refer to capabilities(7). Note that granting some capabilities renders AppArmor confinement for that domain advisory; while open(2), read(2), write(2), etc., will still return error when access is not granted, some capabilities allow loading kernel modules, arbitrary access to IPC, ability to bypass discretionary access controls, and other operations that are typically reserved for the root user.

Network Rules

AppArmor supports simple coarse grained network mediation. The network rule restrict all socket(2) based operations. The mediation done is a course grained check on whether a socket of a given type and family can be created, read, or written. There is no mediation based of port number or protocol beyond tcp, udp, and raw. Network netlink(7) rules may only specify type 'dgram' and 'raw'.

AppArmor network rules are accumulated so that the granted network permissions are the union of all the listed network rule permissions.

AppArmor network rules are broad and general and become more restrictive as further information is specified.

eg.

 network,               #allow access to all networking
 network tcp,           #allow access to tcp
 network inet tcp,      #allow access to tcp only for inet4 addresses
 network inet6 tcp,     #allow access to tcp only for inet6 addresses
 network netlink raw,   #allow access to AF_NETLINK SOCK_RAW

Mount Rules

AppArmor supports mount mediation and allows specifying filesystem types and mount flags. The syntax of mount rules in AppArmor is based on the mount(8) command syntax. Mount rules must contain one of the mount, remount or umount keywords, but all mount conditions are optional. Unspecified optional conditionals are assumed to match all entries (eg, not specifying fstype means all fstypes are matched). Due to the complexity of the mount command and how options may be specified, AppArmor allows specifying conditionals three different ways:

  1. If a conditional is specified using '=', then the rule only grants permission for mounts matching the exactly specified options. For example, an AppArmor policy with the following rule:

        mount options=ro /dev/foo -E<gt> /mnt/,

    Would match:

        $ mount -o ro /dev/foo /mnt

    but not either of these:

        $ mount -o ro,atime /dev/foo /mnt
    
        $ mount -o rw /dev/foo /mnt
  2. If a conditional is specified using 'in', then the rule grants permission for mounts matching any combination of the specified options. For example, if an AppArmor policy has the following rule:

        mount options in (ro,atime) /dev/foo -> /mnt/,

    all of these mount commands will match:

        $ mount -o ro /dev/foo /mnt
    
        $ mount -o ro,atime /dev/foo /mnt
    
        $ mount -o atime /dev/foo /mnt

    but none of these will:

        $ mount -o ro,sync /dev/foo /mnt
    
        $ mount -o ro,atime,sync /dev/foo /mnt
    
        $ mount -o rw /dev/foo /mnt
    
        $ mount -o rw,noatime /dev/foo /mnt
    
        $ mount /dev/foo /mnt
  3. If multiple conditionals are specified in a single mount rule, then the rule grants permission for each set of options. This provides a shorthand when writing mount rules which might help to logically break up a conditional. For example, if an AppArmor policy has the following rule:

        mount options=ro options=atime

    both of these mount commands will match:

        $ mount -o ro /dev/foo /mnt
    
        $ mount -o atime /dev/foo /mnt

    but this one will not:

        $ mount -o ro,atime /dev/foo /mnt

Note that separate mount rules are distinct and the options do not accumulate. For example, these AppArmor mount rules:

    mount options=ro,

    mount options=atime,

are not equivalent to either of these mount rules:

    mount options=(ro,atime),

    mount options in (ro,atime),

To help clarify the flexibility and complexity of mount rules, here are some example rules with accompanying matching commands:

mount,

the 'mount' rule without any conditionals is the most generic and allows any mount. Equivalent to 'mount fstype=** options=** ** -> /**'.

mount /dev/foo,

allow mounting of /dev/foo anywhere with any options. Some matching mount commands:

    $ mount /dev/foo /mnt

    $ mount -t ext3 /dev/foo /mnt

    $ mount -t vfat /dev/foo /mnt

    $ mount -o ro,atime,noexec,nodiratime /dev/foo /srv/some/mountpoint
mount options=ro /dev/foo,

allow mounting of /dev/foo anywhere, as read only. Some matching mount commands:

    $ mount -o ro /dev/foo /mnt

    $ mount -o ro /dev/foo /some/where/else
mount options=(ro,atime) /dev/foo,

allow mount of /dev/foo anywhere, as read only and using inode access times. Some matching mount commands:

    $ mount -o ro,atime /dev/foo /mnt

    $ mount -o ro,atime /dev/foo /some/where/else
mount options in (ro,atime) /dev/foo,

allow mount of /dev/foo anywhere using some combination of 'ro' and 'atime' (see above). Some matching mount commands:

    $ mount -o ro /dev/foo /mnt

    $ mount -o atime /dev/foo /some/where/else

    $ mount -o ro,atime /dev/foo /some/other/place
mount options=ro /dev/foo, mount options=atime /dev/foo,

allow mount of /dev/foo anywhere as read only, and allow mount of /dev/foo anywhere using inode access times. Note this is expressed as two different rules. Matches:

    $ mount -o ro /dev/foo /mnt/1

    $ mount -o atime /dev/foo /mnt/2
mount -> /mnt/**,

allow mounting anything under a directory in /mnt/**. Some matching mount commands:

    $ mount /dev/foo1 /mnt/1

    $ mount -o ro,atime,noexec,nodiratime /dev/foo2 /mnt/deep/path/foo2
mount options=ro -> /mnt/**,

allow mounting anything under /mnt/**, as read only. Some matching mount commands:

    $ mount -o ro /dev/foo1 /mnt/1

    $ mount -o ro /dev/foo2 /mnt/deep/path/foo2
mount fstype=ext3 options=(rw,atime) /dev/sdb1 -> /mnt/stick/,

allow mounting an ext3 filesystem in /dev/sdb1 on /mnt/stick as read/write and using inode access times. Matches only:

    $ mount -o rw,atime /dev/sdb1 /mnt/stick
mount options=(ro, atime) options in (nodev, user) /dev/foo -> /mnt/,

allow mounting /dev/foo on /mmt/ read only and using inode access times or allow mounting /dev/foo on /mnt/ with some combination of 'nodev' and 'user'. Matches only:

    $ mount -o ro,atime /dev/foo /mnt

    $ mount -o nodev /dev/foo /mnt

    $ mount -o user /dev/foo /mnt

    $ mount -o nodev,user /dev/foo /mnt

Pivot Root Rules

AppArmor mediates changing of the root filesystem through the pivot_root(2) system call. The syntax of 'pivot_root' rules in AppArmor is based on the pivot_root(2) system call parameters with the notable exception that the ordering is reversed. The path corresponding to the put_old parameter of pivot_root(2) is optionally specified in the 'pivot_root' rule using the 'oldroot=' prefix.

AppArmor 'pivot_root' rules can specify a profile transition to occur during the pivot_root(2) system call. Note that AppArmor will only transition the process calling pivot_root(2) to the new profile.

The paths specified in 'pivot_root' rules must end with '/' since they are directories.

Here are some example 'pivot_root' rules:

    # Allow any pivot
    pivot_root,

    # Allow pivoting to any new root directory and putting the old root
    # directory at /mnt/root/old/
    pivot_root oldroot=/mnt/root/old/,

    # Allow pivoting the root directory to /mnt/root/
    pivot_root /mnt/root/,

    # Allow pivoting to /mnt/root/ and putting the old root directory at
    # /mnt/root/old/
    pivot_root oldroot=/mnt/root/old/ /mnt/root/,

    # Allow pivoting to /mnt/root/, putting the old root directory at
    # /mnt/root/old/ and transition to the /mnt/root/sbin/init profile
    pivot_root oldroot=/mnt/root/old/ /mnt/root/ -> /mnt/root/sbin/init,

PTrace rules

AppArmor supports mediation of ptrace(2). AppArmor PTrace rules are accumulated so that the granted PTrace permissions are the union of all the listed PTrace rule permissions.

AppArmor PTrace permissions are implied when a rule does not explicitly state an access list. By default, all PTrace permissions are implied.

The trace and tracedby permissions govern ptrace(2) while read and readby govern certain proc(5) filesystem accesses, kcmp(2), futexes (get_robust_list(2)) and perf trace events.

For a ptrace operation to be allowed the profile of the tracing process and the profile of the target task must both have the correct permissions. For example, the profile of the process attaching to another task must have the trace permission for the target task's profile, and the task being traced must have the tracedby permission for the tracing process' profile.

Example AppArmor PTrace rules:

    # Allow all PTrace access
    ptrace,

    # Explicitly allow all PTrace access,
    ptrace (read, readby, trace, tracedby),

    # Explicitly deny use of ptrace(2)
    deny ptrace (trace),

    # Allow unconfined processes (eg, a debugger) to ptrace us
    ptrace (readby, tracedby) peer=unconfined,

    # Allow ptrace of a process running under the /usr/bin/foo profile
    ptrace (trace) peer=/usr/bin/foo,

Signal rules

AppArmor supports mediation of signal(7). AppArmor signal rules are accumulated so that the granted signal permissions are the union of all the listed signal rule permissions.

AppArmor signal permissions are implied when a rule does not explicitly state an access list. By default, all signal permissions are implied.

For the sending of a signal to be allowed, the profile of the sending process and the profile of the target task must both have the correct permissions. For example, the profile of a process sending a signal to another task must have the send permission for the target task's profile, and the task receiving the signal must have a receive permission for the sending process' profile.

Example AppArmor signal rules:

    # Allow all signal access
    signal,

    # Explicitly deny sending the HUP and INT signals
    deny signal (send) set=(hup, int),

    # Allow unconfined processes to send us signals
    signal (receive) peer=unconfined,

    # Allow sending of signals to a process running under the /usr/bin/foo
    # profile
    signal (send) peer=/usr/bin/foo,

    # Allow checking for PID existence
    signal (receive, send) set=("exists"),

    # Allow us to signal ourselves using the built-in @{profile_name} variable
    signal peer=@{profile_name},

    # Allow two real-time signals
    signal set=(rtmin+0 rtmin+32),

DBus rules

AppArmor supports DBus mediation. The mediation is performed in conjunction with the DBus daemon. The DBus daemon verifies that communications over the bus are permitted by AppArmor policy.

AppArmor DBus rules are accumulated so that the granted DBus permissions are the union of all the listed DBus rule permissions.

AppArmor DBus rules are broad and general and become more restrictive as further information is specified. Policy may be specified down to the interface member level (method or signal name), however the contents of messages are not examined.

Some AppArmor DBus permissions are not compatible with all AppArmor DBus rules. The 'bind' permission cannot be used in message rules. The 'send' and 'receive' permissions cannot be used in service rules. The 'eavesdrop' permission cannot be used in rules containing any conditionals outside of the 'bus' conditional.

'r' and 'read' are synonyms for 'receive'. 'w' and 'write' are synonyms for 'send'. 'rw' is a synonym for both 'send' and 'receive'.

AppArmor DBus permissions are implied when a rule does not explicitly state an access list. By default, all DBus permissions are implied. Only message permissions are implied for message rules and only service permissions are implied for service rules.

Example AppArmor DBus rules:

    # Allow all DBus access
    dbus,

    # Explicitly allow all DBus access,
    dbus (send, receive, bind),

    # Deny send/receive/bind access to the session bus
    deny dbus bus=session,

    # Allow bind access for a particular name on any bus
    dbus bind name=com.example.ExampleName,

    # Allow receive access for a particular path and interface
    dbus receive path=/com/example/path interface=com.example.Interface,

    # Deny send/receive access to the system bus for a particular interface
    deny dbus bus=system interface=com.example.ExampleInterface,

    # Allow send access for a particular path, interface, member, and pair of
    # peer names:
    dbus send
         bus=session
         path=/com/example/path
         interface=com.example.Interface
         member=ExampleMethod
         peer=(name=(com.example.ExampleName1|com.example.ExampleName2)),

    # Allow receive access for all unconfined peers
    dbus receive peer=(label=unconfined)),

    # Allow eavesdropping on the system bus
    dbus eavesdrop bus=system,

    # Allow and audit all eavesdropping
    audit dbus eavesdrop,

Unix socket rules

AppArmor supports fine grained mediation of unix domain abstract and anonymous sockets. Unix domain sockets with file system paths are mediated via file access rules.

Abstract unix domain sockets is a nonportable Linux extension of unix domain sockets, see unix(7) for more information.

Unix socket address paths

The sun_path component (aka the socket address) of a unix domain socket is specified by the

  addr=

conditional. If an address conditional is not specified as part of a rule then the rule matches both abstract and anonymous sockets.

In apparmor the address of an abstract unix domain socket begins with the @ character, similar to how they are reported (as paths) by netstat -x. The address then follows and may contain pattern matching and any characters including the null character. In apparmor null characters must be specified by using an escape sequence \000 or \x00. The pattern matching is the same as is used by file path matching so * will not match / even though it has no special meaning with in an abstract socket name. Eg.

  unix addr=@*,

Anonymous unix domain sockets have no sun_path associated with the socket address, however it can be specified with the special none keyword to indicate the rule only applies to anonymous unix domain sockets. Eg.

  unix addr=none,

If the address component of a rule is not specified then the rule applies to both abstract and anonymous sockets.

Unix socket permissions

Unix domain socket rules are accumulated so that the granted unix socket permissions are the union of all the listed unix rule permissions.

Unix domain socket rules are broad and general and become more restrictive as further information is specified. Policy may be specified down to the socket address (aka sun_path) and label level. The content of the communication is not examined.

Unix socket rule permissions are implied when a rule does not explicitly state an access list. By default if a rule does not have an access list all permissions that are compatible with the specified set of local and peer conditionals are implied.

The create, bind, listen, shutdown, getattr, setattr, getopt, and setopt permissions are local socket permissions. They are only applied to the local socket and can't be specified in rules that have a peer component. The accept permission applies to the combination of a local and peer socket. The connect, send, and receive permissions are peer socket permissions.

Only the peer socket permissions will be applied to rules that don't specify permissions and contain a peer component.

Example Unix domain socket rules:

  # Allow all permissions to unix sockets
  unix,

  # Explicitly allow all unix permissions
  unix (create, listen, accept, connect, send, receive, getattr, setattr, setopt, getopt),

  # Explicitly deny unix socket access
  deny unix,

  # Allow create and use of abstract and anonymous sockets for profile_name
  unix peer=(label=@{profile_name}),

  # Allow receiving via unix sockets from unconfined
  unix (receive) peer=(label=unconfined),

  # Allow getattr and shutdown on anonymous sockets
  unix (getattr, shutdown) addr=none,

  # Allow SOCK_STREAM connect, receive and send on an abstract socket @bar
  # with peer running under profile '/foo'
  unix (connect, receive, send) type=stream peer=(label=/foo,addr="@bar"),

  # Allow accepting connections from and receiving from peer running under
  # profile '/bar' on abstract socket '@foo'
  unix (accept, receive) addr=@foo peer=(label=/bar),

Abstract unix domain sockets autobind

Abstract unix domain sockets can autobind to an address. The autobind address is a unique 5 digit string of decimal numbers, eg. @00001. There is nothing that prevents a task from manually binding to addresses with a similar pattern so it is impossible to reliably identify autobind addresses from a regular address.

Interaction of network rules and fine grained unix domain socket rules

The coarse grained networking rules can be used to control unix domain sockets as well. When fine grained unix domain socket mediation is available the coarse grained network rule is mapped into the equivalent unix socket rule.

E.G.

    network unix,  =>  unix,

    network unix stream,   =>  unix stream,

Fine grained mediation rules however can not be lossly converted back to the coarse grained network rule; e.g.

   unix bind addr=@example,

Has no exact match under coarse grained network rules, the closest match is the much wider permission rule of

   network unix,

change_profile rules

AppArmor supports self directed profile transitions via the change_profile api. Change_profile rules control which permissions for which profiles a confined task can transition to. The profile name can contain apparmor pattern matching to specify different profiles.

  change_profile -> **,

The change_profile api allows the transition to be delayed until when a task executes another application. If an exec rule transition is specified for the application and the change_profile api is used to make a transition at exec time, the transition specified by the change_profile api takes precedence.

The Change_profile permission can restrict which profiles can be transitioned to based off of the executable name by specifying the exec condition.

  change_profile /bin/bash -> new_profile,

The restricting of the transition profile to a given executable at exec time is only useful when then current task is allowed to make dynamic decisions about what confinement should be, but the decision set needs to be controlled. A list of profiles or multiple rules can be used to specify the profiles in the set. Eg.

  change_profile /bin/bash -> {new_profile1,new_profile2,new_profile3},

An exec rule can be used to specify a transition for the executable, if the transition should be allowed even if the change_profile api has not been used to select a transition for those available in the change_profile rule set. Eg.

  /bin/bash Px -> new_profile1,
  change_profile /bin/bash -> {new_profile1,new_profile2,new_profile3},

The exec mode dictates whether or not the Linux Kernel's unsafe_exec routines should be used to scrub the environment, similar to setuid programs. (See ld.so(8) for some information on setuid/setgid environment scrubbing.) The safe mode sets up environment scrubbing to occur when the new application is executed and unsafe mode disables AppArmor's requirement for environment scrubbing (the kernel and/or libc may still require environment scrubbing). An exec mode can only be specified when an exec condition is present.

  change_profile safe /bin/bash -> new_profile,

Not all kernels support safe mode and the parser will downgrade rules to unsafe mode in that situation. If no exec mode is specified, the default is safe mode in kernels that support it.

rlimit rules

AppArmor can set and control the resource limits associated with a profile as described in the setrlimit(2) man page.

The AppArmor rlimit controls allow setting of limits and restricting changes of them and these actions can be audited. Enforcement of the set limits is handled by the standard kernel enforcement mechanism for rlimits and will not result in an audited apparmor message if the limit is enforced.

If a profile does not have an rlimit rule associated with a given rlimit then the rlimit is left alone and regular access, including changing the limit, is allowed. However if the profile sets an rlimit then the current limit is checked and if greater than the limit specified in the rule it will be changed to the specified limit.

AppArmor rlimit rules control the hard limit of an application and ensure that if the hard limit is lowered that the soft limit does not exceed the hard limit value.

Eg.

  set rlimit data <= 100M,
  set rlimit nproc <= 10,
  set rlimit nice <= 5,

Variables

AppArmor's policy language allows embedding variables into file rules to enable easier configuration for some common (and pervasive) setups. Variables may have multiple values assigned, but any variable assignments must be made before the start of the profile.

The parser will automatically expand variables to include all values that they have been assigned; it is an error to reference a variable without setting at least one value. You can use empty quotes ("") to explicitly add an empty value.

At the time of this writing, the following variables are defined in the provided AppArmor policy:

  @{HOME}
  @{HOMEDIRS}
  @{multiarch}
  @{pid}
  @{pids}
  @{PROC}
  @{securityfs}
  @{apparmorfs}
  @{sys}
  @{tid}
  @{XDG_DESKTOP_DIR}
  @{XDG_DOWNLOAD_DIR}
  @{XDG_TEMPLATES_DIR}
  @{XDG_PUBLICSHARE_DIR}
  @{XDG_DOCUMENTS_DIR}
  @{XDG_MUSIC_DIR}
  @{XDG_PICTURES_DIR}
  @{XDG_VIDEOS_DIR}

These are defined in files in /etc/apparmor.d/tunables and are used in many of the abstractions described later.

You may also add files in /etc/apparmor.d/tunables/home.d for site-specific customization of @{HOMEDIRS}, /etc/apparmor.d/tunables/multiarch.d for @{multiarch} and /etc/apparmor.d/tunables/xdg-user-dirs.d for @{XDG_*}.

The special @{profile_name} variable is set to the profile name and may be used in all policy.

Alias rules

AppArmor also provides alias rules for remapping paths for site-specific layouts. They are an alternative form of path rewriting to using variables, and are done after variable resolution. Alias rules must occur within the preamble of the profile. System-wide aliases are found in /etc/apparmor.d/tunables/alias, which is included by /etc/apparmor.d/tunables/global. /etc/apparmor.d/tunables/global is typically included at the beginning of an AppArmor profile.

Globbing

File resources may be specified with a globbing syntax similar to that used by popular shells, such as csh(1), bash(1), zsh(1).

*

can substitute for any number of characters, excepting '/'

**

can substitute for any number of characters, including '/'

?

can substitute for any single character excepting '/'

[abc]

will substitute for the single character a, b, or c

[a-c]

will substitute for the single character a, b, or c

[^a-c]

will substitute for any single character not matching a, b or c

{ab,cd}

will expand to one rule to match ab, one rule to match cd

When AppArmor looks up a directory the pathname being looked up will end with a slash (e.g., /var/tmp/); otherwise it will not end with a slash. Only rules that match a trailing slash will match directories. Some examples, none matching the /tmp/ directory itself, are:

/tmp/*

Files directly in /tmp.

/tmp/*/

Directories directly in /tmp.

/tmp/**

Files and directories anywhere underneath /tmp.

/tmp/**/

Directories anywhere underneath /tmp.

Rule Qualifiers

There are several rule qualifiers that can be applied to permission rules. Rule qualifiers can modify the rule and/or permissions within the rule.

allow

Specifies that permissions requests that match the rule are allowed. This is the default value for rules and does not need to be specified. Conflicts with the deny qualifier.

audit

Specifies that permissions requests that match the rule should be recorded to the audit log.

deny

Specifies that permissions requests that match the rule should be denied without logging. Can be combined with 'audit' to enable logging. Conflicts with the allow qualifier.

owner

Specifies that the task must have the same euid/fsuid as the object being referenced by the permission check.

Qualifier Blocks

Rule Qualifiers can be applied to multiple rules at a time by grouping the rules into a rule block.

  audit {
     /foo r,
     network,
  }

#include mechanism

AppArmor provides an easy abstraction mechanism to group common access requirements; this abstraction is an extremely flexible way to grant site-specific rights and makes writing new AppArmor profiles very simple by assembling the needed building blocks for any given program.

The use of '#include' is modelled directly after cpp(1); its use will replace the '#include' statement with the specified file's contents. The leading '#' is optional, and the '#include' keyword can be followed by an option conditional 'if exists' that specifies profile compilation should continue if the specified file or directory is not found.

#include "/absolute/path" specifies that /absolute/path should be used. #include "relative/path" specifies that relative/path should be used, where the path is relative to the current working directory. #include <magic/path> is the most common usage; it will load magic/path relative to a directory specified to apparmor_parser(8). /etc/apparmor.d/ is the AppArmor default.

The supplied AppArmor profiles follow several conventions; the abstractions stored in /etc/apparmor.d/abstractions/ are some large clusters that are used in most profiles. What follows are short descriptions of how some of the abstractions are used.

abstractions/audio

Includes accesses to device files used for audio applications.

abstractions/authentication

Includes access to files and services typically necessary for services that perform user authentication.

abstractions/base

Includes files that should be readable and writable in all profiles.

abstractions/bash

Includes many files used by bash; useful for interactive shells and programs that call system(3).

abstractions/consoles

Includes read and write access to the device files controlling the virtual console, sshd(8), xterm(1), etc. This abstraction is needed for many programs that interact with users.

abstractions/fonts

Includes access to fonts and the font libraries.

abstractions/gnome

Includes read and write access to GNOME configuration files, as well as read access to GNOME libraries.

abstractions/kde

Includes read and write access to KDE configuration files, as well as read access to KDE libraries.

abstractions/kerberosclient

Includes file access rules needed for common kerberos clients.

abstractions/nameservice

Includes file rules to allow DNS, LDAP, NIS, SMB, user and group password databases, services, and protocols lookups.

abstractions/perl

Includes read access to perl modules.

abstractions/user-download
abstractions/user-mail
abstractions/user-manpages
abstractions/user-tmp
abstractions/user-write

Some profiles for typical "user" programs will use these include files to describe rights that users have in the system.

abstractions/wutmp

Includes write access to files used to maintain wtmp(5) and utmp(5) databases, used with the w(1) and associated commands.

abstractions/X

Includes read access to libraries, configuration files, X authentication files, and the X socket.

Some of the abstractions rely on variables that are set in files in the /etc/apparmor.d/tunables/ directory. These variables are currently @{HOME} and @{HOMEDIRS}. Variables cannot be set in profile scope; they can only be set before the profile. Therefore, any profiles that use abstractions should either #include <tunables/global> or otherwise ensure that @{HOME} and @{HOMEDIRS} are set before starting the profile definition. The aa-autodep(8) and aa-genprof(8) utilities will automatically emit #include <tunables/global> in generated profiles.

EXAMPLE

An example AppArmor profile:

        # a variable definition in the preamble
        @{HOME} = /home/*/ /root/

        # a comment about foo.
        /usr/bin/foo {
          /bin/mount          ux,
          /dev/{,u}random     r,
          /etc/ld.so.cache    r,
          /etc/foo.conf       r,
          /etc/foo/*          r,
          /lib/ld-*.so*       rmix,
          /lib/lib*.so*       r,
          /proc/[0-9]**       r,
          /usr/lib/**         r,
          /tmp/foo.pid        wr,
          /tmp/foo.*          lrw,
          /@{HOME}/.foo_file  rw,
          /usr/bin/baz        Cx -> baz,

          # a comment about foo's hat (subprofile), bar.
          ^bar {
            /lib/ld-*.so*       rmix,
            /usr/bin/bar        rmix,
            /var/spool/*        rwl,
          }

          # a comment about foo's subprofile, baz.
          profile baz {
            #include <abstractions/bash>
            owner /proc/[0-9]*/stat r,
            /bin/bash ixr,
            /var/lib/baz/ r,
            owner /var/lib/baz/* rw,
          }
        }

FILES

/etc/init.d/boot.apparmor
/etc/apparmor.d/

KNOWN BUGS

  • Mount options support the use of pattern matching but mount flags are not correctly intersected against specified patterns. Eg, 'mount options=**,' should be equivalent to 'mount,', but it is not. (LP: #965690)

  • The fstype may not be matched against when certain mount command flags are used. Specifically fstype matching currently only works when creating a new mount and not remount, bind, etc.

  • Mount rules with multiple 'options' conditionals are not applied as documented but instead merged such that 'options in (ro,nodev) options in (atime)' is equivalent to 'options in (ro,nodev,atime)'.

  • When specifying mount options with the 'in' conditional, both the positive and negative values match when specifying one or the other. Eg, 'rw' matches when 'ro' is specified and 'dev' matches when 'nodev' is specified such that 'options in (ro,nodev)' is equivalent to 'options in (rw,dev)'.

SEE ALSO

apparmor(7), apparmor_parser(8), aa-complain(1), aa-enforce(1), aa_change_hat(2), mod_apparmor(5), and https://wiki.apparmor.net.

 
apparmor-2.13.3/parser/pod2htmd.tmp0000644000175000017500000000000313502024374014741 0ustar jjjj . apparmor-2.13.3/parser/apparmor.service0000644000175000017500000000143713502024172015711 0ustar jjjj[Unit] Description=Load AppArmor profiles DefaultDependencies=no Before=sysinit.target After=systemd-journald-audit.socket # profile cache After=var.mount var-lib.mount ConditionSecurity=apparmor [Service] Type=oneshot ExecStart=/lib/apparmor/apparmor.systemd reload ExecReload=/lib/apparmor/apparmor.systemd reload # systemd maps 'restart' to 'stop; start' which means removing AppArmor confinement # from running processes (and not being able to re-apply it later). # Upstream systemd developers refused to implement an option that allows overriding # this behaviour, therefore we have to make ExecStop a no-op to error out on the # safe side. # # If you really want to unload all AppArmor profiles, run aa-teardown ExecStop=/bin/true RemainAfterExit=yes [Install] WantedBy=multi-user.target apparmor-2.13.3/parser/af_unix.cc0000644000175000017500000002662413502024172014453 0ustar jjjj/* * Copyright (c) 2014 * Canonical, Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical * Ltd. */ #include #include #include #include #include #include #include #include "network.h" #include "parser.h" #include "profile.h" #include "af_unix.h" int parse_unix_mode(const char *str_mode, int *mode, int fail) { return parse_X_mode("unix", AA_VALID_NET_PERMS, str_mode, mode, fail); } static struct supported_cond supported_conds[] = { { "addr", true, false, false, either_cond }, { NULL, false, false, false, local_cond }, /* sentinal */ }; void unix_rule::move_conditionals(struct cond_entry *conds) { struct cond_entry *ent; list_for_each(conds, ent) { if (!cond_check(supported_conds, ent, false, "unix") && !move_base_cond(ent, false)) { yyerror("unix rule: invalid conditional '%s'\n", ent->name); continue; } if (strcmp(ent->name, "addr") == 0) { move_conditional_value("unix socket", &addr, ent); if (addr[0] != '@' && strcmp(addr, "none") != 0) yyerror("unix rule: invalid value for addr='%s'\n", addr); } /* TODO: add conditionals for * listen queue length * attrs that can be read/set * ops that can be read/set * allow in on * type, protocol * local label match, and set */ } } void unix_rule::move_peer_conditionals(struct cond_entry *conds) { struct cond_entry *ent; list_for_each(conds, ent) { if (!cond_check(supported_conds, ent, true, "unix") && !move_base_cond(ent, true)) { yyerror("unix rule: invalid peer conditional '%s'\n", ent->name); continue; } if (strcmp(ent->name, "addr") == 0) { move_conditional_value("unix", &peer_addr, ent); if (peer_addr[0] != '@' && strcmp(peer_addr, "none") != 0) yyerror("unix rule: invalid value for addr='%s'\n", peer_addr); } } } unix_rule::unix_rule(unsigned int type_p, bool audit_p, bool denied): af_rule("unix"), addr(NULL), peer_addr(NULL) { if (type_p != 0xffffffff) { sock_type_n = type_p; sock_type = strdup(net_find_type_name(type_p)); if (!sock_type) yyerror("socket rule: invalid socket type '%d'", type_p); } mode = AA_VALID_NET_PERMS; audit = audit_p ? AA_VALID_NET_PERMS : 0; deny = denied; } unix_rule::unix_rule(int mode_p, struct cond_entry *conds, struct cond_entry *peer_conds): af_rule("unix"), addr(NULL), peer_addr(NULL), audit(0), deny(0) { move_conditionals(conds); move_peer_conditionals(peer_conds); if (mode_p) { mode = mode_p; if (mode & ~AA_VALID_NET_PERMS) yyerror("mode contains invalid permissions for unix socket rules\n"); else if ((mode & ~AA_PEER_NET_PERMS) && has_peer_conds()) yyerror("unix socket 'create', 'shutdown', 'setattr', 'getattr', 'bind', 'listen', 'setopt', and/or 'getopt' accesses cannot be used with peer socket conditionals\n"); } else { mode = AA_VALID_NET_PERMS; } free_cond_list(conds); free_cond_list(peer_conds); } ostream &unix_rule::dump_local(ostream &os) { af_rule::dump_local(os); if (addr) os << "addr='" << addr << "'"; return os; } ostream &unix_rule::dump_peer(ostream &os) { af_rule::dump_peer(os); if (peer_addr) os << "addr='" << peer_addr << "'"; return os; } int unix_rule::expand_variables(void) { int error = af_rule::expand_variables(); if (error) return error; error = expand_entry_variables(&addr); if (error) return error; error = expand_entry_variables(&peer_addr); if (error) return error; return 0; } /* do we want to warn once/profile or just once per compile?? */ static void warn_once(const char *name, const char *msg) { static const char *warned_name = NULL; if (warned_name != name) { cerr << "Warning from profile " << name << " ("; if (current_filename) cerr << current_filename; else cerr << "stdin"; cerr << "): " << msg << "\n"; warned_name = name; } } static void warn_once(const char *name) { if (warnflags & WARN_RULE_NOT_ENFORCED) warn_once(name, "extended network unix socket rules not enforced"); } static void writeu16(std::ostringstream &o, int v) { u16 tmp = htobe16((u16) v); u8 *byte1 = (u8 *)&tmp; u8 *byte2 = byte1 + 1; o << "\\x" << std::setfill('0') << std::setw(2) << std::hex << static_cast(*byte1); o << "\\x" << std::setfill('0') << std::setw(2) << std::hex << static_cast(*byte2); } #define CMD_ADDR 1 #define CMD_LISTEN 2 #define CMD_ACCEPT 3 #define CMD_OPT 4 void unix_rule::downgrade_rule(Profile &prof) { unsigned int mask = (unsigned int) -1; if (!prof.net.allow && !prof.alloc_net_table()) yyerror(_("Memory allocation error.")); if (sock_type_n != -1) mask = 1 << sock_type_n; if (deny) { prof.net.deny[AF_UNIX] |= mask; if (!audit) prof.net.quiet[AF_UNIX] |= mask; } else { prof.net.allow[AF_UNIX] |= mask; if (audit) prof.net.audit[AF_UNIX] |= mask; } } static uint32_t map_perms(uint32_t mask) { return (mask & 0x7f) | ((mask & (AA_NET_GETATTR | AA_NET_SETATTR)) << (AA_OTHER_SHIFT - 8)) | ((mask & (AA_NET_ACCEPT | AA_NET_BIND | AA_NET_LISTEN)) >> 4) | /* 2 + (AA_OTHER_SHIFT - 20) */ ((mask & (AA_NET_SETOPT | AA_NET_GETOPT)) >> 5); /* 5 + (AA_OTHER_SHIFT - 24) */ } void unix_rule::write_to_prot(std::ostringstream &buffer) { buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_NET; writeu16(buffer, AF_UNIX); if (sock_type) writeu16(buffer, sock_type_n); else buffer << ".."; if (proto) writeu16(buffer, proto_n); else buffer << ".."; } bool unix_rule::write_addr(std::ostringstream &buffer, const char *addr) { std::string buf; pattern_t ptype; if (addr) { int pos; if (strcmp(addr, "none") == 0) { /* anonymous */ buffer << "\\x01"; } else { /* skip leading @ */ ptype = convert_aaregex_to_pcre(addr + 1, 0, glob_null, buf, &pos); if (ptype == ePatternInvalid) return false; /* kernel starts abstract with \0 */ buffer << "\\x00"; buffer << buf; } } else /* match any addr or anonymous */ buffer << ".*"; /* todo: change to out of band separator */ buffer << "\\x00"; return true; } bool unix_rule::write_label(std::ostringstream &buffer, const char *label) { std::string buf; pattern_t ptype; if (label) { int pos; ptype = convert_aaregex_to_pcre(label, 0, glob_default, buf, &pos); if (ptype == ePatternInvalid) return false; /* kernel starts abstract with \0 */ buffer << buf; } else buffer << default_match_pattern; return true; } /* General Layout * * Local socket end point perms * CLASS_NET AF TYPE PROTO local (addr\0label) \0 cmd cmd_option * ^ ^ ^ ^ ^ * | | | | | * stub perm | | | | * | | | | * sub stub perm | | | * | | | * create perm | | * | | * | | * bind, accept, get/set attr | * | * listen, set/get opt perm * * * peer socket end point perms * CLASS_NET AF TYPE PROTO local(addr\0label\0) cmd_addr peer(addr\0label ) * ^ * | * send/receive connect/accept perm * * NOTE: accept is encoded twice, locally to check if a socket is allowed * to accept, and then as a pair to test that it can accept the pair. */ int unix_rule::gen_policy_re(Profile &prof) { std::ostringstream buffer; std::string buf; int mask = mode; /* always generate a downgraded rule. This doesn't change generated * policy size and allows the binary policy to be loaded against * older kernels and be enforced to the best of the old network * rules ability */ downgrade_rule(prof); if (!kernel_supports_unix) { if (kernel_supports_network) { /* only warn if we are building against a kernel * that requires downgrading */ if (warnflags & WARN_RULE_DOWNGRADED) warn_once(prof.name, "downgrading extended network unix socket rule to generic network rule\n"); /* TODO: add ability to abort instead of downgrade */ return RULE_OK; } warn_once(prof.name); return RULE_NOT_SUPPORTED; } write_to_prot(buffer); if ((mask & AA_NET_CREATE) && !has_peer_conds()) { buf = buffer.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_CREATE), map_perms(audit & AA_NET_CREATE), dfaflags)) goto fail; mask &= ~AA_NET_CREATE; } if (mask) { /* local addr */ if (!write_addr(buffer, addr)) goto fail; /* local label option */ if (!write_label(buffer, label)) goto fail; /* seperator */ buffer << "\\x00"; /* create already masked off */ int local_mask = has_peer_conds() ? AA_NET_ACCEPT : AA_LOCAL_NET_PERMS & ~AA_LOCAL_NET_CMD; if (mask & local_mask) { buf = buffer.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(mask & local_mask), map_perms(audit & local_mask), dfaflags)) goto fail; } if ((mask & AA_NET_LISTEN) && !has_peer_conds()) { std::ostringstream tmp(buffer.str()); tmp.seekp(0, ios_base::end); tmp << "\\x" << std::setfill('0') << std::setw(2) << std::hex << CMD_LISTEN; /* TODO: backlog conditional: for now match anything*/ tmp << ".."; buf = tmp.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_LISTEN), map_perms(audit & AA_NET_LISTEN), dfaflags)) goto fail; } if ((mask & AA_NET_OPT) && !has_peer_conds()) { std::ostringstream tmp(buffer.str()); tmp.seekp(0, ios_base::end); tmp << "\\x" << std::setfill('0') << std::setw(2) << std::hex << CMD_OPT; /* TODO: sockopt conditional: for now match anything */ tmp << ".."; buf = tmp.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(mask & AA_NET_OPT), map_perms(audit & AA_NET_OPT), dfaflags)) goto fail; } mask &= ~AA_LOCAL_NET_PERMS | AA_NET_ACCEPT; } /* if (mask) */ if (mask & AA_PEER_NET_PERMS) { /* cmd selector */ buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << CMD_ADDR; /* local addr */ if (!write_addr(buffer, peer_addr)) goto fail; /* local label option */ if (!write_label(buffer, peer_label)) goto fail; buf = buffer.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(mode & AA_PEER_NET_PERMS), map_perms(audit), dfaflags)) goto fail; } return RULE_OK; fail: return RULE_ERROR; } apparmor-2.13.3/parser/aa-teardown.8.html0000644000175000017500000000306613502024374015750 0ustar jjjj
 

NAME

aa-teardown - unload all AppArmor profiles

SYNOPSIS

aa-teardown

DESCRIPTION

aa-teardown unloads all AppArmor profiles

BUGS

If you find any bugs, please report them at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7), apparmor.d(5), and https://wiki.apparmor.net.

 
apparmor-2.13.3/parser/af_rule.cc0000644000175000017500000001044513502024172014431 0ustar jjjj/* * Copyright (c) 2014 * Canonical, Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical * Ltd. */ #include #include #include #include #include #include #include #include "network.h" #include "parser.h" #include "profile.h" #include "parser_yacc.h" #include "af_rule.h" /* need to move this table to stl */ static struct supported_cond supported_conds[] = { { "type", true, false, false, local_cond }, { "protocol", false, false, false, local_cond }, { "label", true, false, false, peer_cond }, { NULL, false, false, false, local_cond }, /* eol sentinal */ }; bool af_rule::cond_check(struct supported_cond *conds, struct cond_entry *ent, bool peer, const char *rname) { struct supported_cond *i; for (i = conds; i->name; i++) { if (strcmp(ent->name, i->name) != 0) continue; if (!i->supported) yyerror("%s rule: '%s' conditional is not currently supported\n", rname, ent->name); if (!peer && (i->side == peer_cond)) yyerror("%s rule: '%s' conditional is only valid in the peer expression\n", rname, ent->name); if (peer && (i->side == local_cond)) yyerror("%s rule: '%s' conditional is not allowed in the peer expression\n", rname, ent->name); if (!ent->eq && !i->in) yyerror("%s rule: keyword 'in' is not allowed in '%s' socket conditional\n", rname, ent->name); if (list_len(ent->vals) > 1 && !i->multivalue) yyerror("%s rule: conditional '%s' only supports a single value\n", rname, ent->name); return true; } /* not in support table */ return false; } /* generic af supported conds. * returns: true if processed, else false */ int af_rule::move_base_cond(struct cond_entry *ent, bool peer) { if (!cond_check(supported_conds, ent, peer, "unknown")) return false; if (strcmp(ent->name, "type") == 0) { move_conditional_value("socket rule", &sock_type, ent); sock_type_n = net_find_type_val(sock_type); if (sock_type_n == -1) yyerror("socket rule: invalid socket type '%s'", sock_type); } else if (strcmp(ent->name, "protocol") == 0) { yyerror("socket rule: 'protocol' conditional is not currently supported\n"); } else if (strcmp(ent->name, "label") == 0) { if (!peer) move_conditional_value("unix", &label, ent); else move_conditional_value("unix", &peer_label, ent); } else return false; return true; } ostream &af_rule::dump_prefix(ostream &os) { if (audit) os << "audit "; if (deny) os << "deny "; return os; } ostream &af_rule::dump_local(ostream &os) { if (mode != AA_VALID_NET_PERMS) { os << " ("; if (mode & AA_NET_SEND) os << "send "; if (mode & AA_NET_RECEIVE) os << "receive "; if (mode & AA_NET_CREATE) os << "create "; if (mode & AA_NET_SHUTDOWN) os << "shutdown "; if (mode & AA_NET_CONNECT) os << "connect "; if (mode & AA_NET_SETATTR) os << "setattr "; if (mode & AA_NET_GETATTR) os << "getattr "; if (mode & AA_NET_BIND) os << "bind "; if (mode & AA_NET_ACCEPT) os << "accept "; if (mode & AA_NET_LISTEN) os << "listen "; if (mode & AA_NET_SETOPT) os << "setopt "; if (mode & AA_NET_GETOPT) os << "getopt "; os << ")"; } if (sock_type) os << " type=" << sock_type; if (proto) os << " protocol=" << proto; return os; } ostream &af_rule::dump_peer(ostream &os) { if (peer_label) os << " label=\"" << peer_label << "\""; return os; } ostream &af_rule::dump(ostream &os) { dump_prefix(os); os << af_name; dump_local(os); if (has_peer_conds()) { os << " peer=("; dump_peer(os); os << ")"; } os << ",\n"; return os; } int af_rule::expand_variables(void) { int error = expand_entry_variables(&label); if (error) return error; error = expand_entry_variables(&peer_label); if (error) return error; return 0; } apparmor-2.13.3/parser/profile.h0000644000175000017500000001061513502024172014315 0ustar jjjj/* * Copyright (c) 2012 * Canonical, Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifndef __AA_PROFILE_H #define __AA_PROFILE_H #include #include #include #include "parser.h" #include "rule.h" #include "libapparmor_re/aare_rules.h" #include "network.h" class Profile; class block { public: }; struct deref_profileptr_lt { bool operator()(Profile * const &lhs, Profile * const &rhs) const; }; class ProfileList { public: set list; typedef set::iterator iterator; iterator begin() { return list.begin(); } iterator end() { return list.end(); } ProfileList() { }; virtual ~ProfileList() { clear(); } virtual bool empty(void) { return list.empty(); } virtual pair insert(Profile *); virtual void erase(ProfileList::iterator pos); void clear(void); void dump(void); void dump_profile_names(bool children); }; class flagvals { public: int hat; int complain; int audit; int path; void dump(void) { printf("Profile Mode:\t"); if (complain) printf("Complain"); else printf("Enforce"); if (audit) printf(", Audit"); if (hat) printf(", Hat"); printf("\n"); } }; struct capabilities { uint64_t allow; uint64_t audit; uint64_t deny; uint64_t quiet; capabilities(void) { allow = audit = deny = quiet = 0; } void dump() { if (allow != 0ull) __debug_capabilities(allow, "Capabilities"); if (audit != 0ull) __debug_capabilities(audit, "Audit Caps"); if (deny != 0ull) __debug_capabilities(deny, "Deny Caps"); if (quiet != 0ull) __debug_capabilities(quiet, "Quiet Caps"); }; }; struct dfa_stuff { aare_rules *rules; void *dfa; size_t size; dfa_stuff(void): rules(NULL), dfa(NULL), size(0) { } }; class Profile { public: char *ns; char *name; char *attachment; struct alt_name *altnames; void *xmatch; size_t xmatch_size; int xmatch_len; /* char *sub_name; */ /* subdomain name or NULL */ /* int default_deny; */ /* TRUE or FALSE */ int local; int local_mode; /* true if local, not hat */ int local_audit; Profile *parent; flagvals flags; struct capabilities caps; struct network net; struct aa_rlimits rlimits; char *exec_table[AA_EXEC_COUNT]; struct cod_entry *entries; RuleList rule_ents; ProfileList hat_table; struct dfa_stuff dfa; struct dfa_stuff policy; Profile(void) { ns = name = attachment = NULL; altnames = NULL; xmatch = NULL; xmatch_size = 0; xmatch_len = 0; local = local_mode = local_audit = 0; parent = NULL; flags = { 0, 0, 0, 0}; rlimits = {0, {}}; std::fill(exec_table, exec_table + AA_EXEC_COUNT, (char *)NULL); entries = NULL; }; virtual ~Profile(); bool operator<(Profile const &rhs)const { if (ns) { if (rhs.ns) { int res = strcmp(ns, rhs.ns); if (res != 0) return res < 0; } else return false; } else if (rhs.ns) return true; return strcmp(name, rhs.name) < 0; } void dump(void) { if (ns) printf("Ns:\t\t%s\n", ns); if (name) printf("Name:\t\t%s\n", name); else printf("Name:\t\t\n"); if (local) { if (parent) printf("Local To:\t%s\n", parent->name); else printf("Local To:\t\n"); } flags.dump(); caps.dump(); net.dump(); if (entries) debug_cod_entries(entries); for (RuleList::iterator i = rule_ents.begin(); i != rule_ents.end(); i++) { (*i)->dump(cout); } printf("\n"); hat_table.dump(); } bool alloc_net_table(); std::string hname(void) { if (!parent) return name; return parent->hname() + "//" + name; } /* assumes ns is set as part of profile creation */ std::string fqname(void) { if (parent) return parent->fqname() + "//" + name; else if (!ns) return hname(); return ":" + std::string(ns) + "://" + hname(); } std::string get_name(bool fqp) { if (fqp) return fqname(); return hname(); } void dump_name(bool fqp) { cout << get_name(fqp);; } }; #endif /* __AA_PROFILE_H */ apparmor-2.13.3/parser/common_optarg.h0000644000175000017500000000264213502024172015522 0ustar jjjj/* * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 * NOVELL (All rights reserved) * * Copyright (c) 2010 - 2014 * Canonical Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical, * Ltd. */ #ifndef __AA_COMMON_OPTARG_H #define __AA_COMMON_OPTARG_H #include "libapparmor_re/apparmor_re.h" /* * flag: 1 - allow no- inversion * flag: 2 - flags specified should be masked off */ typedef struct { int control; const char *option; const char *desc; dfaflags_t flags; } optflag_table_t; extern optflag_table_t dumpflag_table[]; extern optflag_table_t optflag_table[]; void print_flag_table(optflag_table_t *table); int handle_flag_table(optflag_table_t *table, const char *optarg, dfaflags_t *flags); void display_dump(const char *command); void display_optimize(const char *command); #endif /* __AA_COMMON_OPTARG_H */ apparmor-2.13.3/parser/mount.h0000644000175000017500000001060213502024172014013 0ustar jjjj/* * Copyright (c) 2010 * Canonical, Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical * Ltd. */ #ifndef __AA_MOUNT_H #define __AA_MOUNT_H #include #include "parser.h" #include "rule.h" #define MS_RDONLY (1 << 0) #define MS_RW 0 #define MS_NOSUID (1 << 1) #define MS_SUID 0 #define MS_NODEV (1 << 2) #define MS_DEV 0 #define MS_NOEXEC (1 << 3) #define MS_EXEC 0 #define MS_SYNC (1 << 4) #define MS_ASYNC 0 #define MS_REMOUNT (1 << 5) #define MS_MAND (1 << 6) #define MS_NOMAND 0 #define MS_DIRSYNC (1 << 7) #define MS_NODIRSYNC 0 #define MS_NOATIME (1 << 10) #define MS_ATIME 0 #define MS_NODIRATIME (1 << 11) #define MS_DIRATIME 0 #define MS_BIND (1 << 12) #define MS_MOVE (1 << 13) #define MS_REC (1 << 14) #define MS_VERBOSE (1 << 15) #define MS_SILENT (1 << 15) #define MS_LOAD 0 #define MS_ACL (1 << 16) #define MS_NOACL 0 #define MS_UNBINDABLE (1 << 17) #define MS_PRIVATE (1 << 18) #define MS_SLAVE (1 << 19) #define MS_SHARED (1 << 20) #define MS_RELATIME (1 << 21) #define MS_NORELATIME 0 #define MS_IVERSION (1 << 23) #define MS_NOIVERSION 0 #define MS_STRICTATIME (1 << 24) #define MS_NOUSER (1 << 31) #define MS_USER 0 /* Only use MS_REC when defining these macros. Please use the macros from here * on and don't make assumptions about the presence of MS_REC. */ #define MS_RBIND (MS_BIND | MS_REC) #define MS_RUNBINDABLE (MS_UNBINDABLE | MS_REC) #define MS_RPRIVATE (MS_PRIVATE | MS_REC) #define MS_RSLAVE (MS_SLAVE | MS_REC) #define MS_RSHARED (MS_SHARED | MS_REC) #define MS_ALL_FLAGS (MS_RDONLY | MS_NOSUID | MS_NODEV | MS_NOEXEC | \ MS_SYNC | MS_REMOUNT | MS_MAND | MS_DIRSYNC | \ MS_NOATIME | MS_NODIRATIME | MS_BIND | MS_RBIND | \ MS_MOVE | MS_VERBOSE | MS_ACL | \ MS_UNBINDABLE | MS_RUNBINDABLE | \ MS_PRIVATE | MS_RPRIVATE | \ MS_SLAVE | MS_RSLAVE | MS_SHARED | MS_RSHARED | \ MS_RELATIME | MS_IVERSION | MS_STRICTATIME | MS_USER) /* set of flags we don't use but define (but not with the kernel values) * for MNT_FLAGS */ #define MS_ACTIVE 0 #define MS_BORN 0 #define MS_KERNMOUNT 0 /* from kernel fs/namespace.c - set of flags masked off */ #define MNT_FLAGS (MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | \ MS_BORN | MS_NOATIME | MS_NODIRATIME | MS_RELATIME| \ MS_KERNMOUNT | MS_STRICTATIME) #define MS_BIND_FLAGS (MS_BIND | MS_RBIND) #define MS_MAKE_FLAGS ((MS_UNBINDABLE | MS_RUNBINDABLE | \ MS_PRIVATE | MS_RPRIVATE | \ MS_SLAVE | MS_RSLAVE | MS_SHARED | MS_RSHARED) | \ (MS_ALL_FLAGS & ~(MNT_FLAGS))) #define MS_MOVE_FLAGS (MS_MOVE) #define MS_CMDS (MS_MOVE | MS_REMOUNT | MS_BIND | MS_RBIND | \ MS_UNBINDABLE | MS_RUNBINDABLE | MS_PRIVATE | MS_RPRIVATE | \ MS_SLAVE | MS_RSLAVE | MS_SHARED | MS_RSHARED) #define MS_REMOUNT_FLAGS (MS_ALL_FLAGS & ~(MS_CMDS & ~MS_REMOUNT & ~MS_BIND & ~MS_RBIND)) #define MNT_SRC_OPT 1 #define MNT_DST_OPT 2 #define MNT_COND_FSTYPE 1 #define MNT_COND_OPTIONS 2 #define AA_MAY_PIVOTROOT 1 #define AA_MAY_MOUNT 2 #define AA_MAY_UMOUNT 4 #define AA_MATCH_CONT 0x40 #define AA_AUDIT_MNT_DATA AA_MATCH_CONT #define AA_DUMMY_REMOUNT 0x40000000 /* dummy perm for remount rule - is * remapped to a mount option*/ class mnt_rule: public rule_t { public: char *mnt_point; char *device; char *trans; struct value_list *dev_type; struct value_list *opts; unsigned int flags, inv_flags; int allow, audit; int deny; mnt_rule(struct cond_entry *src_conds, char *device_p, struct cond_entry *dst_conds unused, char *mnt_point_p, int allow_p); virtual ~mnt_rule() { free_value_list(opts); free_value_list(dev_type); free(device); free(mnt_point); free(trans); } virtual ostream &dump(ostream &os); virtual int expand_variables(void); virtual int gen_policy_re(Profile &prof); virtual void post_process(Profile &prof unused); }; int is_valid_mnt_cond(const char *name, int src); #endif /* __AA_MOUNT_H */ apparmor-2.13.3/parser/dbus.h0000644000175000017500000000322313502024172013607 0ustar jjjj/* * Copyright (c) 2013 * Canonical, Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical * Ltd. */ #ifndef __AA_DBUS_H #define __AA_DBUS_H #include "parser.h" #include "rule.h" #include "profile.h" extern int parse_dbus_mode(const char *str_mode, int *mode, int fail); class dbus_rule: public rule_t { void move_conditionals(struct cond_entry *conds); public: char *bus; /** * Be careful! ->name can be the subject or the peer name, depending on * whether the rule is a bind rule or a send/receive rule. See the * comments in new_dbus_entry() for details. */ char *name; char *peer_label; char *path; char *interface; char *member; int mode; int audit; int deny; dbus_rule(int mode_p, struct cond_entry *conds, struct cond_entry *peer_conds); virtual ~dbus_rule() { free(bus); free(name); free(peer_label); free(path); free(interface); free(member); }; virtual ostream &dump(ostream &os); virtual int expand_variables(void); virtual int gen_policy_re(Profile &prof); virtual void post_process(Profile &prof unused) { }; }; #endif /* __AA_DBUS_H */ apparmor-2.13.3/parser/parser_include.c0000644000175000017500000001613513502024172015652 0ustar jjjj/* * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 * NOVELL (All rights reserved) * Copyright (c) 2010 - 2012 * Canonical Ltd. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Canonical, Ltd. */ /* Handle subdomain includes, as a straight forward preprocessing phase. While we are at it we will strip comments. Why? because it made it easier. We support 2 types of includes #include which searches for the first occurance of name in the subdomain directory path. #include "name" which will search for a relative or absolute pathed file -p : preprocess only. Dump output to stdout -I path : add a path to be search by #include < > -b path : set the base path to something other than /etc/subdomain.d */ #include #include #include #include #include #include #include #include #include #include #include #include "lib.h" #include "parser.h" #include "parser_include.h" /* An array of search directories, I sure hope 100's enough */ #define MAX_PATH 100 /* maximum depth of nesting */ #define MAX_NEST_LEVEL 100 /* Location of the subdomain.conf file */ #ifdef SUBDOMAIN_CONFDIR #define SUBDOMAIN_CONF SUBDOMAIN_CONFDIR "/subdomain.conf" #else /* !defined SUBDOMAIN_CONFDIR */ #define SUBDOMAIN_CONF "/etc/subdomain.conf" #endif /* SUBDOMAIN_CONFDIR */ static char *path[MAX_PATH] = { NULL }; static int npath = 0; static int fgetline(FILE * f, char *buffer, size_t len); static int stripcomment(char *s); static char *stripblanks(char *s); /* default base directory is /etc/subdomain.d, it can be overriden with the -b option. */ const char *basedir; static const char *default_basedir = "/etc/apparmor.d"; static const char *old_basedir = "/etc/subdomain.d"; /* set up basedir so that it can be overridden/used later. */ void init_base_dir(void) { int rc; struct stat sbuf; /* basedir should always start out NULL; if not, something's * wrong.*/ assert(basedir == NULL); rc = stat(default_basedir, &sbuf); if (rc == 0 && S_ISDIR(sbuf.st_mode)) { basedir = default_basedir; return; } rc = stat(old_basedir, &sbuf); if (rc == 0 && S_ISDIR(sbuf.st_mode)) { basedir = old_basedir; return; } } /* Set the base dir. Used to change default path for relative includes */ void set_base_dir(char *dir) { char *t; int i, rc; struct stat sbuf; t = strndup(dir, PATH_MAX); if (!t) { PERROR(_("Error: Out of memory.\n")); return; } /*strip trailing /'s */ for (i = strlen(t) - 1; i >= 0 && t[i] == '/'; i--) t[i] = 0; rc = stat(t, &sbuf); if (rc == -1 || !S_ISDIR(sbuf.st_mode)) { PERROR(_("Error: basedir %s is not a directory, skipping.\n"), t); free(t); return; } basedir = t; return; } /* Add a directory to the search path. */ int add_search_dir(const char *dir) { char *t; size_t len; if (npath >= MAX_PATH) { PERROR(_("Error: Could not add directory %s to search path.\n"), dir); return 0; } if (!dir) return 1; len = strlen(dir); if (len == 0) return 1; t = strdup(dir); if (t == NULL) { PERROR(_("Error: Could not allocate memory.\n")); return 0; } /*strip trailing /'s */ while (len > 0 && t[--len] == '/') t[len] = '\0'; path[npath] = t; npath++; return 1; } /* Parse Subdomain.conf and put the default dirs in place. subdomain.conf is a shell sourcable file we only parse entries starting with SUBDOMAIN_PATH= if there are multiple entries with SUBDOMAIN_PATH= each will get added. SUBDOMAIN_PATH=/etc/subdomain.d:/etc/subdomain.d/include is the same as SUBDOMAIN_PATH=/etc/subdomain.d SUBDOMAIN_PATH=/etc/subdomain.d/include */ void parse_default_paths(void) { autofclose FILE *f; char buf[1024]; char *t, *s; int saved_npath = npath; f = fopen(SUBDOMAIN_CONF, "r"); if (f == NULL) goto out; memset(buf, 0, sizeof(buf)); while (fgetline(f, buf, 1024)) { if (stripcomment(buf) && (t = strstr(buf, "SUBDOMAIN_PATH="))) { t += 15; /* handle : separating path elements */ do { s = strchr(t, ':'); if (s) *s = 0; if (!add_search_dir(stripblanks(t))) break; if (s) t = s + 1; } while (s != NULL); } } /* if subdomain.conf doesn't set a base search dir set it to this */ out: if (npath - saved_npath == 0) { add_search_dir(basedir); } } FILE *search_path(char *filename, char **fullpath) { FILE *newf = NULL; char *buf = NULL; int i; for (i = 0; i < npath; i++) { if (asprintf(&buf, "%s/%s", path[i], filename) < 0) { perror("asprintf"); exit(1); } newf = fopen(buf, "r"); if (newf && fullpath) *fullpath = buf; else free(buf); buf = NULL; if (newf) break; } return newf; } /* get a line from the file. If it is to long truncate it. */ static int fgetline(FILE * f, char *buffer, size_t len) { char *b = buffer; int c; while (((c = fgetc(f)) != EOF) && (c != '\n') && (strlen(buffer) < len - 1)) { *b = c; b++; } *b = '\0'; if (c != EOF) return 1; return 0; } /* If there is a comment null terminate the string, return strlen of the stripped string*/ static int stripcomment(char *s) { char *t = s; while (*s != '#' && *s != 0) s++; *s = 0; return strlen(t); } static char *stripblanks(char *s) { char *c; while (isspace(*s)) s++; c = s; while (!isspace(*s) && *s != 0) s++; *s = 0; return c; } struct include_stack_t { char *filename; int lineno; struct include_stack_t *next; }; struct include_stack_t *include_stack_head = NULL; static void start_include_position(const char *filename) { if (current_filename) free(current_filename); current_filename = strdup(filename ? filename : "stdin"); current_lineno = 1; } void push_include_stack(char *filename) { struct include_stack_t *include = NULL; include = (struct include_stack_t *) malloc(sizeof(*include)); if (!include) { perror("malloc of included file stack tracker"); /* failures in this area are non-fatal */ return; } include->filename = strdup(current_filename); include->lineno = current_lineno; include->next = include_stack_head; include_stack_head = include; start_include_position(filename); } void pop_include_stack(void) { struct include_stack_t *include = NULL; if (!include_stack_head) return; include = include_stack_head; include_stack_head = include->next; if (current_filename) free(current_filename); current_filename = include->filename; current_lineno = include->lineno; free(include); } void reset_include_stack(const char *filename) { while (include_stack_head) pop_include_stack(); start_include_position(filename); } apparmor-2.13.3/parser/rc.apparmor.functions0000644000175000017500000003123213502024172016660 0ustar jjjj#!/bin/sh # ---------------------------------------------------------------------- # Copyright (c) 1999-2008 NOVELL (All rights reserved) # Copyright (c) 2009-2012 Canonical Ltd. (All rights reserved) # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Novell, Inc. # ---------------------------------------------------------------------- # rc.apparmor.functions by Steve Beattie # # NOTE: rc.apparmor initscripts that source this file need to implement # the following set of functions: # aa_action # aa_log_action_start # aa_log_action_end # aa_log_success_msg # aa_log_warning_msg # aa_log_failure_msg # aa_log_skipped_msg # aa_log_daemon_msg # aa_log_end_msg # Some nice defines that we use CONFIG_DIR=/etc/apparmor MODULE=apparmor OLD_MODULE=subdomain if [ -f "${CONFIG_DIR}/${MODULE}.conf" ] ; then APPARMOR_CONF="${CONFIG_DIR}/${MODULE}.conf" elif [ -f "${CONFIG_DIR}/${OLD_MODULE}.conf" ] ; then APPARMOR_CONF="${CONFIG_DIR}/${OLD_MODULE}.conf" elif [ -f "/etc/immunix/subdomain.conf" ] ; then aa_log_warning_msg "/etc/immunix/subdomain.conf is deprecated, use ${CONFIG_DIR}/subdomain.conf instead" APPARMOR_CONF="/etc/immunix/subdomain.conf" elif [ -f "/etc/subdomain.conf" ] ; then aa_log_warning_msg "/etc/subdomain.conf is deprecated, use ${CONFIG_DIR}/subdomain.conf instead" APPARMOR_CONF="/etc/subdomain.conf" else aa_log_warning_msg "Unable to find config file in ${CONFIG_DIR}, installation problem?" fi # Read configuration options from /etc/subdomain.conf, default is to # warn if subdomain won't load. SUBDOMAIN_MODULE_PANIC="warn" SUBDOMAIN_ENABLE_OWLSM="no" APPARMOR_ENABLE_AAEVENTD="no" if [ -f "${APPARMOR_CONF}" ] ; then #parse the conf file to see what we should do . "${APPARMOR_CONF}" fi PARSER=/sbin/apparmor_parser # SUBDOMAIN_DIR and APPARMOR_DIR might be defined in subdomain.conf|apparmor.conf if [ -d "${APPARMOR_DIR}" ] ; then PROFILE_DIR=${APPARMOR_DIR} elif [ -d "${SUBDOMAIN_DIR}" ] ; then PROFILE_DIR=${SUBDOMAIN_DIR} elif [ -d /etc/apparmor.d ] ; then PROFILE_DIR=/etc/apparmor.d elif [ -d /etc/subdomain.d ] ; then PROFILE_DIR=/etc/subdomain.d fi ABSTRACTIONS="-I${PROFILE_DIR}" AA_EV_BIN=/usr/sbin/aa-eventd AA_EV_PIDFILE=/var/run/aa-eventd.pid AA_STATUS=/usr/sbin/aa-status SD_EV_BIN=/usr/sbin/sd-event-dispatch.pl SD_EV_PIDFILE=/var/run/sd-event-dispatch.init.pid SD_STATUS=/usr/sbin/subdomain_status SECURITYFS=/sys/kernel/security SUBDOMAINFS_MOUNTPOINT=$(grep subdomainfs /etc/fstab | \ sed -e 's|^[[:space:]]*[^[:space:]]\+[[:space:]]\+\(/[^[:space:]]*\)[[:space:]]\+subdomainfs.*$|\1|' 2> /dev/null) # keep exit status from parser during profile load. 0 is good, 1 is bad STATUS=0 # Test if the apparmor "module" is present. is_apparmor_present() { local modules=$1 shift while [ $# -gt 0 ] ; do modules="$modules|$1" shift done # check for subdomainfs version of module grep -qE "^($modules)[[:space:]]" /proc/modules [ $? -ne 0 -a -d /sys/module/apparmor ] return $? } # This set of patterns to skip needs to be kept in sync with # AppArmor.pm::isSkippableFile() # returns 0 if profile should NOT be skipped # returns 1 on verbose skip # returns 2 on silent skip skip_profile() { local profile=$1 if [ "${profile%.rpmnew}" != "${profile}" -o \ "${profile%.rpmsave}" != "${profile}" -o \ "${profile%.orig}" != "${profile}" -o \ "${profile%.rej}" != "${profile}" -o \ -e "${PROFILE_DIR}/disable/`basename ${profile}`" -o \ "${profile%\~}" != "${profile}" ] ; then return 1 fi # Silently ignore the dpkg, pacman, and xbps files if [ "${profile%.dpkg-new}" != "${profile}" -o \ "${profile%.dpkg-old}" != "${profile}" -o \ "${profile%.dpkg-dist}" != "${profile}" -o \ "${profile%.dpkg-bak}" != "${profile}" -o \ "${profile%.dpkg-remove}" != "${profile}" -o \ "${profile%.pacsave}" != "${profile}" -o \ "${profile%.pacnew}" != "${profile}" ] ; then return 2 fi if echo "${profile}" | egrep -q '^.+\.new-[0-9\.]+_[0-9]+$'; then return 2 fi return 0 } force_complain() { local profile=$1 # if profile not in complain mode if ! egrep -q "^/.*[ \t]+flags[ \t]*=[ \t]*\([ \t]*complain[ \t]*\)[ \t]+{" $profile ; then local link="${PROFILE_DIR}/force-complain/`basename ${profile}`" if [ -e "$link" ] ; then aa_log_warning_msg "found $link, forcing complain mode" return 0 fi fi return 1 } parse_profiles() { # get parser arg case "$1" in load) PARSER_ARGS="--add" PARSER_MSG="Loading AppArmor profiles " ;; reload) PARSER_ARGS="--replace" PARSER_MSG="Reloading AppArmor profiles " ;; *) aa_log_failure_msg "required 'load' or 'reload'" exit 1 ;; esac aa_log_action_start "$PARSER_MSG" # run the parser on all of the apparmor profiles if [ ! -f "$PARSER" ]; then aa_log_failure_msg "AppArmor parser not found" aa_log_action_end 1 exit 1 fi if [ ! -d "$PROFILE_DIR" ]; then aa_log_failure_msg "Profile directory not found" aa_log_action_end 1 exit 1 fi if [ -z "$(ls $PROFILE_DIR/)" ]; then aa_log_failure_msg "No profiles found" aa_log_action_end 1 return 1 fi for profile in $PROFILE_DIR/*; do skip_profile "${profile}" skip=$? # Ignore skip status == 2 (silent skip) if [ "$skip" -eq 1 ] ; then aa_log_skipped_msg "$profile" logger -t "AppArmor(init)" -p daemon.warn "Skipping profile $profile" STATUS=2 continue elif [ "$skip" -ne 0 ]; then continue fi if [ -f "${profile}" ] ; then COMPLAIN="" if force_complain "${profile}" ; then COMPLAIN="-C" fi $PARSER $ABSTRACTIONS $PARSER_ARGS $COMPLAIN "$profile" > /dev/null if [ $? -ne 0 ]; then aa_log_failure_msg "$profile failed to load" STATUS=1 fi fi done if [ $STATUS -eq 2 ]; then STATUS=0 fi aa_log_action_end "$STATUS" return $STATUS } profiles_names_list() { # run the parser on all of the apparmor profiles if [ ! -f "$PARSER" ]; then aa_log_failure_msg "- AppArmor parser not found" exit 1 fi if [ ! -d "$PROFILE_DIR" ]; then aa_log_failure_msg "- Profile directory not found" exit 1 fi for profile in $PROFILE_DIR/*; do if skip_profile "${profile}" && [ -f "${profile}" ] ; then LIST_ADD=$($PARSER $ABSTRACTIONS -N "$profile" ) if [ $? -eq 0 ]; then echo "$LIST_ADD" fi fi done } failstop_system() { level=$(runlevel | cut -d" " -f2) if [ $level -ne "1" ] ; then aa_log_failure_msg "- could not start AppArmor. Changing to runlevel 1" telinit 1; return -1; fi aa_log_failure_msg "- could not start AppArmor." return -1 } module_panic() { # the module failed to load, determine what action should be taken case "$SUBDOMAIN_MODULE_PANIC" in "warn"|"WARN") return 1 ;; "panic"|"PANIC") failstop_system rc=$? return $rc ;; *) aa_log_failure_msg "- invalid AppArmor module fail option" return -1 ;; esac } is_apparmor_loaded() { if ! is_securityfs_mounted ; then mount_securityfs fi mount_subdomainfs if [ -f "${SECURITYFS}/${MODULE}/profiles" ]; then SFS_MOUNTPOINT="${SECURITYFS}/${MODULE}" return 0 fi if [ -f "${SECURITYFS}/${OLD_MODULE}/profiles" ]; then SFS_MOUNTPOINT="${SECURITYFS}/${OLD_MODULE}" return 0 fi if [ -f "${SUBDOMAINFS_MOUNTPOINT}/profiles" ]; then SFS_MOUNTPOINT=${SUBDOMAINFS_MOUNTPOINT} return 0 fi # check for subdomainfs version of module is_apparmor_present apparmor subdomain return $? } is_securityfs_mounted() { test -d ${SECURITYFS} -a -d /sys/fs/cgroup/systemd || grep -q securityfs /proc/filesystems && grep -q securityfs /proc/mounts return $? } mount_securityfs() { if grep -q securityfs /proc/filesystems ; then aa_action "Mounting securityfs on ${SECURITYFS}" \ mount -t securityfs securityfs "${SECURITYFS}" return $? fi return 0 } mount_subdomainfs() { # for backwords compatibility if grep -q subdomainfs /proc/filesystems && \ ! grep -q subdomainfs /proc/mounts && \ [ -n "${SUBDOMAINFS_MOUNTPOINT}" ]; then aa_action "Mounting subdomainfs on ${SUBDOMAINFS_MOUNTPOINT}" \ mount "${SUBDOMAINFS_MOUNTPOINT}" return $? fi return 0 } unmount_subdomainfs() { SUBDOMAINFS=$(grep subdomainfs /proc/mounts | cut -d" " -f2 2> /dev/null) if [ -n "${SUBDOMAINFS}" ]; then aa_action "Unmounting subdomainfs" umount ${SUBDOMAINFS} fi } load_module() { local rc=0 if modinfo -F filename apparmor > /dev/null 2>&1 ; then MODULE=apparmor elif modinfo -F filename ${OLD_MODULE} > /dev/null 2>&1 ; then MODULE=${OLD_MODULE} fi if ! is_apparmor_present apparmor subdomain ; then aa_action "Loading AppArmor module" /sbin/modprobe -q $MODULE $1 rc=$? if [ $rc -ne 0 ] ; then module_panic rc=$? if [ $rc -ne 0 ] ; then exit $rc fi fi fi if ! is_apparmor_loaded ; then return 1 fi return $rc } apparmor_start() { aa_log_daemon_msg "Starting AppArmor" if ! is_apparmor_loaded ; then load_module rc=$? if [ $rc -ne 0 ] ; then aa_log_end_msg $rc return $rc fi fi if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then aa_log_failure_msg "Loading AppArmor profiles - failed, Do you have the correct privileges?" aa_log_end_msg 1 return 1 fi configure_owlsm # if there is anything in the profiles file don't load if ! read line < "$SFS_MOUNTPOINT/profiles"; then parse_profiles load else aa_log_skipped_msg ": already loaded with profiles." return 0 fi aa_log_end_msg 0 return 0 } remove_profiles() { # removing profiles as we directly read from subdomainfs # doesn't work, since we are removing entries which screws up # our position. Lets hope there are never enough profiles to # overflow the variable if ! is_apparmor_loaded ; then aa_log_failure_msg "AppArmor module is not loaded" return 1 fi if [ ! -w "$SFS_MOUNTPOINT/.remove" ] ; then aa_log_failure_msg "Root privileges not available" return 1 fi if [ ! -x "${PARSER}" ] ; then aa_log_failure_msg "Unable to execute AppArmor parser" return 1 fi retval=0 # We filter child profiles as removing the parent will remove # the children sed -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles" | \ LC_COLLATE=C sort | grep -v // | { while read profile ; do echo -n "$profile" > "$SFS_MOUNTPOINT/.remove" rc=$? if [ ${rc} -ne 0 ] ; then retval=${rc} fi done return ${retval} } } apparmor_stop() { aa_log_daemon_msg "Unloading AppArmor profiles " remove_profiles rc=$? aa_log_end_msg $rc return $rc } apparmor_kill() { aa_log_daemon_msg "Unloading AppArmor modules " if ! is_apparmor_loaded ; then aa_log_failure_msg "AppArmor module is not loaded" return 1 fi unmount_subdomainfs if is_apparmor_present apparmor ; then MODULE=apparmor elif is_apparmor_present subdomain ; then MODULE=subdomain else aa_log_failure_msg "AppArmor is builtin" return 1 fi /sbin/modprobe -qr $MODULE rc=$? aa_log_end_msg $rc return $rc } __apparmor_restart() { if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then aa_log_failure_msg "Loading AppArmor profiles - failed, Do you have the correct privileges?" return 4 fi aa_log_daemon_msg "Restarting AppArmor" configure_owlsm parse_profiles reload rc=$? aa_log_end_msg $rc return $rc } apparmor_restart() { if ! is_apparmor_loaded ; then apparmor_start rc=$? return $rc fi __apparmor_restart return $? } apparmor_try_restart() { if ! is_apparmor_loaded ; then return 0 fi __apparmor_restart return $? } configure_owlsm () { if [ "${SUBDOMAIN_ENABLE_OWLSM}" = "yes" -a -f ${SFS_MOUNTPOINT}/control/owlsm ] ; then # Sigh, the "sh -c" is necessary for the SuSE aa_action # and it can't be abstracted out as a seperate function, as # that breaks under RedHat's action, which needs a # binary to invoke. aa_action "Enabling OWLSM extension" sh -c "echo -n \"1\" > \"${SFS_MOUNTPOINT}/control/owlsm\"" elif [ -f "${SFS_MOUNTPOINT}/control/owlsm" ] ; then aa_action "Disabling OWLSM extension" sh -c "echo -n \"0\" > \"${SFS_MOUNTPOINT}/control/owlsm\"" fi } apparmor_status () { if test -x ${AA_STATUS} ; then ${AA_STATUS} --verbose return $? fi if test -x ${SD_STATUS} ; then ${SD_STATUS} --verbose return $? fi if ! is_apparmor_loaded ; then echo "AppArmor is not loaded." rc=1 else echo "AppArmor is enabled." rc=0 fi echo "Install the apparmor-utils package to receive more detailed" echo "status information here (or examine ${SFS_MOUNTPOINT} directly)." return $rc } apparmor-2.13.3/parser/ptrace.cc0000644000175000017500000000731313502024172014272 0ustar jjjj/* * Copyright (c) 2014 * Canonical, Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical * Ltd. */ #include "parser.h" #include "profile.h" #include "ptrace.h" #include #include #include #include int parse_ptrace_mode(const char *str_mode, int *mode, int fail) { return parse_X_mode("ptrace", AA_VALID_PTRACE_PERMS, str_mode, mode, fail); } void ptrace_rule::move_conditionals(struct cond_entry *conds) { struct cond_entry *cond_ent; list_for_each(conds, cond_ent) { /* for now disallow keyword 'in' (list) */ if (!cond_ent->eq) yyerror("keyword \"in\" is not allowed in ptrace rules\n"); if (strcmp(cond_ent->name, "peer") == 0) { move_conditional_value("ptrace", &peer_label, cond_ent); } else { yyerror("invalid ptrace rule conditional \"%s\"\n", cond_ent->name); } } } ptrace_rule::ptrace_rule(int mode_p, struct cond_entry *conds): peer_label(NULL), audit(0), deny(0) { if (mode_p) { if (mode_p & ~AA_VALID_PTRACE_PERMS) yyerror("mode contains invalid permissions for ptrace\n"); mode = mode_p; } else { mode = AA_VALID_PTRACE_PERMS; } move_conditionals(conds); free_cond_list(conds); } ostream &ptrace_rule::dump(ostream &os) { if (audit) os << "audit "; if (deny) os << "deny "; os << "ptrace"; if (mode != AA_VALID_PTRACE_PERMS) { os << " ("; if (mode & AA_MAY_READ) os << "read "; if (mode & AA_MAY_READBY) os << "readby "; if (mode & AA_MAY_TRACE) os << "trace "; if (mode & AA_MAY_TRACEDBY) os << "tracedby "; os << ")"; } if (peer_label) os << " " << peer_label; os << ",\n"; return os; } int ptrace_rule::expand_variables(void) { return expand_entry_variables(&peer_label); } /* do we want to warn once/profile or just once per compile?? */ static void warn_once(const char *name) { static const char *warned_name = NULL; if ((warnflags & WARN_RULE_NOT_ENFORCED) && warned_name != name) { cerr << "Warning from profile " << name << " ("; if (current_filename) cerr << current_filename; else cerr << "stdin"; cerr << ") ptrace rules not enforced\n"; warned_name = name; } } int ptrace_rule::gen_policy_re(Profile &prof) { std::ostringstream buffer; std::string buf; pattern_t ptype; int pos; /* ?? do we want to generate the rules in the policy so that it * the compile could be used on another kernel unchanged?? * Current caching doesn't support this but in the future maybe */ if (!kernel_supports_ptrace) { warn_once(prof.name); return RULE_NOT_SUPPORTED; } /* always generate a label and ptrace entry */ buffer << "(" << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_LABEL << "|)"; buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_PTRACE; if (peer_label) { ptype = convert_aaregex_to_pcre(peer_label, 0, glob_default, buf, &pos); if (ptype == ePatternInvalid) goto fail; buffer << buf; } else { buffer << anyone_match_pattern; } buf = buffer.str(); if (mode & AA_VALID_PTRACE_PERMS) { if (!prof.policy.rules->add_rule(buf.c_str(), deny, mode, audit, dfaflags)) goto fail; } return RULE_OK; fail: return RULE_ERROR; } apparmor-2.13.3/parser/parser_regex.c0000644000175000017500000007452613502024172015351 0ustar jjjj/* * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 * NOVELL (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. */ #include #include #include #include #include #include #include #include #include /* #define DEBUG */ #include "lib.h" #include "parser.h" #include "profile.h" #include "libapparmor_re/apparmor_re.h" #include "libapparmor_re/aare_rules.h" #include "policydb.h" #include "rule.h" enum error_type { e_no_error, e_parse_error, }; /* Filters out multiple slashes (except if the first two are slashes, * that's a distinct namespace in linux) and trailing slashes. * NOTE: modifies in place the contents of the path argument */ static void filter_slashes(char *path) { char *sptr, *dptr; BOOL seen_slash = 0; if (!path || (strlen(path) < 2)) return; sptr = dptr = path; /* special case for linux // namespace */ if (sptr[0] == '/' && sptr[1] == '/' && sptr[2] != '/') { sptr += 2; dptr += 2; } while (*sptr) { if (*sptr == '/') { if (seen_slash) { ++sptr; } else { *dptr++ = *sptr++; seen_slash = TRUE; } } else { seen_slash = 0; if (dptr < sptr) { *dptr++ = *sptr++; } else { dptr++; sptr++; } } } *dptr = 0; } static error_type append_glob(std::string &pcre, int glob, const char *default_glob, const char *null_glob) { switch (glob) { case glob_default: pcre.append(default_glob); break; case glob_null: pcre.append(null_glob); break; default: PERROR(_("%s: Invalid glob type %d\n"), progname, glob); return e_parse_error; break; } return e_no_error; } /* converts the apparmor regex in aare and appends pcre regex output * to pcre string */ pattern_t convert_aaregex_to_pcre(const char *aare, int anchor, int glob, std::string& pcre, int *first_re_pos) { #define update_re_pos(X) if (!(*first_re_pos)) { *first_re_pos = (X); } #define MAX_ALT_DEPTH 50 *first_re_pos = 0; int ret = TRUE; /* flag to indicate input error */ enum error_type error; const char *sptr; pattern_t ptype; BOOL bEscape = 0; /* flag to indicate escape */ int ingrouping = 0; /* flag to indicate {} context */ int incharclass = 0; /* flag to indicate [ ] context */ int grouping_count[MAX_ALT_DEPTH] = {0}; error = e_no_error; ptype = ePatternBasic; /* assume no regex */ sptr = aare; if (dfaflags & DFA_DUMP_RULE_EXPR) fprintf(stderr, "aare: %s -> ", aare); if (anchor) /* anchor beginning of regular expression */ pcre.append("^"); while (error == e_no_error && *sptr) { switch (*sptr) { case '\\': /* concurrent escapes are allowed now and * output as two consecutive escapes so that * pcre won't interpret them * \\\{...\\\} will be emitted as \\\{...\\\} * for pcre matching. For string matching * and globbing only one escape is output * this is done by stripping later */ if (bEscape) { pcre.append("\\\\"); } else { bEscape = TRUE; ++sptr; continue; /*skip turning bEscape off */ } /* bEscape */ break; case '*': if (bEscape) { /* '*' is a PCRE special character */ /* We store an escaped *, in case we * end up using this regex buffer (i.e another * non-escaped regex follows) */ pcre.append("\\*"); } else { if ((pcre.length() > 0) && pcre[pcre.length() - 1] == '/') { #if 0 // handle comment containing use // of C comment characters // /* /*/ and /** to describe paths // // modify what is emitted for * and ** // when used as the only path // component // ex. // /* /*/ /**/ /** // this prevents these expressions // from matching directories or // invalid paths // in these case * and ** must // match at least 1 character to // get a valid path element. // ex. // /foo/* -> should not match /foo/ // /foo/*bar -> should match /foo/bar // /*/foo -> should not match //foo #endif const char *s = sptr; while (*s == '*') s++; if (*s == '/' || !*s) error = append_glob(pcre, glob, "[^/\\x00]", "[^/]"); } if (*(sptr + 1) == '*') { /* is this the first regex form we * have seen and also the end of * pattern? If so, we can use * optimised tail globbing rather * than full regex. */ update_re_pos(sptr - aare); if (*(sptr + 2) == '\0' && ptype == ePatternBasic) { ptype = ePatternTailGlob; } else { ptype = ePatternRegex; } error = append_glob(pcre, glob, "[^\\x00]*", ".*"); sptr++; } else { update_re_pos(sptr - aare); ptype = ePatternRegex; error = append_glob(pcre, glob, "[^/\\x00]*", "[^/]*"); } /* *(sptr+1) == '*' */ } /* bEscape */ break; case '?': if (bEscape) { /* ? is not a PCRE regex character * so no need to escape, just skip * transform */ pcre.append(1, *sptr); } else { update_re_pos(sptr - aare); ptype = ePatternRegex; pcre.append("[^/\\x00]"); } break; case '[': if (bEscape) { /* [ is a PCRE special character */ pcre.append("\\["); } else { update_re_pos(sptr - aare); incharclass = 1; ptype = ePatternRegex; pcre.append(1, *sptr); } break; case ']': if (bEscape) { /* ] is a PCRE special character */ pcre.append("\\]"); } else { if (incharclass == 0) { error = e_parse_error; PERROR(_("%s: Regex grouping error: Invalid close ], no matching open [ detected\n"), progname); } incharclass = 0; pcre.append(1, *sptr); } break; case '{': if (bEscape) { /* { is a PCRE special character */ pcre.append("\\{"); } else { if (incharclass) { /* don't expand inside [] */ pcre.append("{"); } else { update_re_pos(sptr - aare); ingrouping++; if (ingrouping >= MAX_ALT_DEPTH) { error = e_parse_error; PERROR(_("%s: Regex grouping error: Exceeded maximum nesting of {}\n"), progname); } else { grouping_count[ingrouping] = 0; ptype = ePatternRegex; pcre.append("("); } } /* incharclass */ } break; case '}': if (bEscape) { /* { is a PCRE special character */ pcre.append("\\}"); } else { if (incharclass) { /* don't expand inside [] */ pcre.append("}"); } else { if (grouping_count[ingrouping] == 0) { error = e_parse_error; PERROR(_("%s: Regex grouping error: Invalid number of items between {}\n"), progname); } ingrouping--; if (ingrouping < 0) { error = e_parse_error; PERROR(_("%s: Regex grouping error: Invalid close }, no matching open { detected\n"), progname); ingrouping = 0; } pcre.append(")"); } /* incharclass */ } /* bEscape */ break; case ',': if (bEscape) { if (incharclass) { /* escape inside char class is a * valid matching char for '\' */ pcre.append("\\,"); } else { /* ',' is not a PCRE regex character * so no need to escape, just skip * transform */ pcre.append(1, *sptr); } } else { if (ingrouping && !incharclass) { grouping_count[ingrouping]++; pcre.append("|"); } else { pcre.append(1, *sptr); } } break; /* these are special outside of character * classes but not in them */ case '^': case '$': if (incharclass) { pcre.append(1, *sptr); } else { pcre.append("\\"); pcre.append(1, *sptr); } break; /* * Not a subdomain regex, but needs to be * escaped as it is a pcre metacharacter which * we don't want to support. We always escape * these, so no need to check bEscape */ case '.': case '+': case '|': case '(': case ')': pcre.append("\\"); // fall through to default default: if (bEscape) { const char *pos = sptr; int c; if ((c = str_escseq(&pos, "")) != -1) { /* valid escape we don't want to * interpret here */ pcre.append("\\"); pcre.append(sptr, pos - sptr); sptr += (pos - sptr) - 1; } else { /* quoting mark used for something that * does not need to be quoted; give a * warning */ pwarn("Character %c was quoted " "unnecessarily, dropped preceding" " quote ('\\') character\n", *sptr); pcre.append(1, *sptr); } } else pcre.append(1, *sptr); break; } /* switch (*sptr) */ bEscape = FALSE; ++sptr; } /* while error == e_no_error && *sptr) */ if (ingrouping > 0 || incharclass) { error = e_parse_error; PERROR(_("%s: Regex grouping error: Unclosed grouping or character class, expecting close }\n"), progname); } if ((error == e_no_error) && bEscape) { /* trailing backslash quote */ error = e_parse_error; PERROR(_("%s: Regex error: trailing '\\' escape character\n"), progname); } /* anchor end and terminate pattern string */ if ((error == e_no_error) && anchor) { pcre.append("$"); } /* check error again, as above STORE may have set it */ if (error != e_no_error) { PERROR(_("%s: Unable to parse input line '%s'\n"), progname, aare); ret = FALSE; goto out; } out: if (ret == FALSE) ptype = ePatternInvalid; if (dfaflags & DFA_DUMP_RULE_EXPR) fprintf(stderr, "%s\n", pcre.c_str()); return ptype; } static const char *local_name(const char *name) { const char *t; for (t = strstr(name, "//") ; t ; t = strstr(name, "//")) name = t + 2; return name; } static int process_profile_name_xmatch(Profile *prof) { std::string tbuf; pattern_t ptype; const char *name; /* don't filter_slashes for profile names */ if (prof->attachment) name = prof->attachment; else name = local_name(prof->name); ptype = convert_aaregex_to_pcre(name, 0, glob_default, tbuf, &prof->xmatch_len); if (ptype == ePatternBasic) prof->xmatch_len = strlen(name); if (ptype == ePatternInvalid) { PERROR(_("%s: Invalid profile name '%s' - bad regular expression\n"), progname, name); return FALSE; } else if (ptype == ePatternBasic && !(prof->altnames || prof->attachment)) { /* no regex so do not set xmatch */ prof->xmatch = NULL; prof->xmatch_len = 0; prof->xmatch_size = 0; } else { /* build a dfa */ aare_rules *rules = new aare_rules(); if (!rules) return FALSE; if (!rules->add_rule(tbuf.c_str(), 0, AA_MAY_EXEC, 0, dfaflags)) { delete rules; return FALSE; } if (prof->altnames) { struct alt_name *alt; list_for_each(prof->altnames, alt) { int len; tbuf.clear(); ptype = convert_aaregex_to_pcre(alt->name, 0, glob_default, tbuf, &len); if (!rules->add_rule(tbuf.c_str(), 0, AA_MAY_EXEC, 0, dfaflags)) { delete rules; return FALSE; } } } prof->xmatch = rules->create_dfa(&prof->xmatch_size, &prof->xmatch_len, dfaflags); delete rules; if (!prof->xmatch) return FALSE; } return TRUE; } static int warn_change_profile = 1; static bool is_change_profile_mode(int mode) { /** * A change_profile entry will have the AA_CHANGE_PROFILE bit set. * It could also have the (AA_EXEC_BITS | ALL_AA_EXEC_UNSAFE) bits * set by the frontend parser. That means that it is incorrect to * identify change_profile modes using a test like this: * * (mode & ~AA_CHANGE_PROFILE) * * The above test would incorrectly return true on a * change_profile mode that has the * (AA_EXEC_BITS | ALL_AA_EXEC_UNSAFE) bits set. */ return mode & AA_CHANGE_PROFILE; } static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) { std::string tbuf; pattern_t ptype; int pos; if (!entry) /* shouldn't happen */ return TRUE; if (!is_change_profile_mode(entry->mode)) filter_slashes(entry->name); ptype = convert_aaregex_to_pcre(entry->name, 0, glob_default, tbuf, &pos); if (ptype == ePatternInvalid) return FALSE; entry->pattern_type = ptype; /* ix implies m but the apparmor module does not add m bit to * dfa states like it does for pcre */ if ((entry->mode >> AA_OTHER_SHIFT) & AA_EXEC_INHERIT) entry->mode |= AA_OLD_EXEC_MMAP << AA_OTHER_SHIFT; if ((entry->mode >> AA_USER_SHIFT) & AA_EXEC_INHERIT) entry->mode |= AA_OLD_EXEC_MMAP << AA_USER_SHIFT; /* the link bit on the first pair entry should not get masked * out by a deny rule, as both pieces of the link pair must * match. audit info for the link is carried on the second * entry of the pair * * So if a deny rule only record it if there are permissions other * than link in the entry. * TODO: split link and change_profile entries earlier */ if (entry->deny) { if ((entry->mode & ~AA_LINK_BITS) && !is_change_profile_mode(entry->mode) && !dfarules->add_rule(tbuf.c_str(), entry->deny, entry->mode & ~(AA_LINK_BITS | AA_CHANGE_PROFILE), entry->audit & ~(AA_LINK_BITS | AA_CHANGE_PROFILE), dfaflags)) return FALSE; } else if (!is_change_profile_mode(entry->mode)) { if (!dfarules->add_rule(tbuf.c_str(), entry->deny, entry->mode, entry->audit, dfaflags)) return FALSE; } if (entry->mode & (AA_LINK_BITS)) { /* add the pair rule */ std::string lbuf; int perms = AA_LINK_BITS & entry->mode; const char *vec[2]; int pos; vec[0] = tbuf.c_str(); if (entry->link_name) { ptype = convert_aaregex_to_pcre(entry->link_name, 0, glob_default, lbuf, &pos); if (ptype == ePatternInvalid) return FALSE; if (entry->subset) perms |= LINK_TO_LINK_SUBSET(perms); vec[1] = lbuf.c_str(); } else { perms |= LINK_TO_LINK_SUBSET(perms); vec[1] = "/[^/].*"; } if (!dfarules->add_rule_vec(entry->deny, perms, entry->audit & AA_LINK_BITS, 2, vec, dfaflags)) return FALSE; } if (is_change_profile_mode(entry->mode)) { const char *vec[3]; std::string lbuf, xbuf; autofree char *ns = NULL; autofree char *name = NULL; int index = 1; uint32_t onexec_perms = AA_ONEXEC; if ((warnflags & WARN_RULE_DOWNGRADED) && entry->audit && warn_change_profile) { /* don't have profile name here, so until this code * gets refactored just throw out a generic warning */ fprintf(stderr, "Warning kernel does not support audit modifier for change_profile rule.\n"); warn_change_profile = 0; } if (entry->onexec) { ptype = convert_aaregex_to_pcre(entry->onexec, 0, glob_default, xbuf, &pos); if (ptype == ePatternInvalid) return FALSE; vec[0] = xbuf.c_str(); } else /* allow change_profile for all execs */ vec[0] = "/[^/\\x00][^\\x00]*"; if (!kernel_supports_stacking) { bool stack; if (!parse_label(&stack, &ns, &name, tbuf.c_str(), false)) { return FALSE; } if (stack) { fprintf(stderr, _("The current kernel does not support stacking of named transitions: %s\n"), tbuf.c_str()); return FALSE; } if (ns) vec[index++] = ns; vec[index++] = name; } else { vec[index++] = tbuf.c_str(); } /* regular change_profile rule */ if (!dfarules->add_rule_vec(entry->deny, AA_CHANGE_PROFILE | onexec_perms, 0, index - 1, &vec[1], dfaflags)) return FALSE; /* onexec rules - both rules are needed for onexec */ if (!dfarules->add_rule_vec(entry->deny, onexec_perms, 0, 1, vec, dfaflags)) return FALSE; /** * pick up any exec bits, from the frontend parser, related to * unsafe exec transitions */ onexec_perms |= (entry->mode & (AA_EXEC_BITS | ALL_AA_EXEC_UNSAFE)); if (!dfarules->add_rule_vec(entry->deny, onexec_perms, 0, index, vec, dfaflags)) return FALSE; } return TRUE; } int post_process_entries(Profile *prof) { int ret = TRUE; struct cod_entry *entry; list_for_each(prof->entries, entry) { if (!process_dfa_entry(prof->dfa.rules, entry)) ret = FALSE; } return ret; } int process_profile_regex(Profile *prof) { int error = -1; if (!process_profile_name_xmatch(prof)) goto out; prof->dfa.rules = new aare_rules(); if (!prof->dfa.rules) goto out; if (!post_process_entries(prof)) goto out; if (prof->dfa.rules->rule_count > 0) { int xmatch_len = 0; prof->dfa.dfa = prof->dfa.rules->create_dfa(&prof->dfa.size, &xmatch_len, dfaflags); delete prof->dfa.rules; prof->dfa.rules = NULL; if (!prof->dfa.dfa) goto out; /* if (prof->dfa_size == 0) { PERROR(_("profile %s: has merged rules (%s) with " "multiple x modifiers\n"), prof->name, (char *) prof->dfa); free(prof->dfa); prof->dfa = NULL; goto out; } */ } error = 0; out: return error; } int build_list_val_expr(std::string& buffer, struct value_list *list) { struct value_list *ent; pattern_t ptype; int pos; if (!list) { buffer.append(default_match_pattern); return TRUE; } buffer.append("("); ptype = convert_aaregex_to_pcre(list->value, 0, glob_default, buffer, &pos); if (ptype == ePatternInvalid) goto fail; list_for_each(list->next, ent) { buffer.append("|"); ptype = convert_aaregex_to_pcre(ent->value, 0, glob_default, buffer, &pos); if (ptype == ePatternInvalid) goto fail; } buffer.append(")"); return TRUE; fail: return FALSE; } int convert_entry(std::string& buffer, char *entry) { pattern_t ptype; int pos; if (entry) { ptype = convert_aaregex_to_pcre(entry, 0, glob_default, buffer, &pos); if (ptype == ePatternInvalid) return FALSE; } else { buffer.append(default_match_pattern); } return TRUE; } int clear_and_convert_entry(std::string& buffer, char *entry) { buffer.clear(); return convert_entry(buffer, entry); } int post_process_policydb_ents(Profile *prof) { for (RuleList::iterator i = prof->rule_ents.begin(); i != prof->rule_ents.end(); i++) { if ((*i)->gen_policy_re(*prof) == RULE_ERROR) return FALSE; } return TRUE; } #define MAKE_STR(X) #X #define CLASS_STR(X) "\\d" MAKE_STR(X) #define MAKE_SUB_STR(X) "\\000" MAKE_STR(X) #define CLASS_SUB_STR(X, Y) MAKE_STR(X) MAKE_SUB_STR(Y) static const char *mediates_file = CLASS_STR(AA_CLASS_FILE); static const char *mediates_mount = CLASS_STR(AA_CLASS_MOUNT); static const char *mediates_dbus = CLASS_STR(AA_CLASS_DBUS); static const char *mediates_signal = CLASS_STR(AA_CLASS_SIGNAL); static const char *mediates_ptrace = CLASS_STR(AA_CLASS_PTRACE); static const char *mediates_extended_net = CLASS_STR(AA_CLASS_NET); static const char *mediates_net_unix = CLASS_SUB_STR(AA_CLASS_NET, AF_UNIX); int process_profile_policydb(Profile *prof) { int error = -1; prof->policy.rules = new aare_rules(); if (!prof->policy.rules) goto out; if (!post_process_policydb_ents(prof)) goto out; /* insert entries to show indicate what compiler/policy expects * to be supported */ /* note: this activates fs based unix domain sockets mediation on connect */ if (kernel_abi_version > 5 && !prof->policy.rules->add_rule(mediates_file, 0, AA_MAY_READ, 0, dfaflags)) goto out; if (kernel_supports_mount && !prof->policy.rules->add_rule(mediates_mount, 0, AA_MAY_READ, 0, dfaflags)) goto out; if (kernel_supports_dbus && !prof->policy.rules->add_rule(mediates_dbus, 0, AA_MAY_READ, 0, dfaflags)) goto out; if (kernel_supports_signal && !prof->policy.rules->add_rule(mediates_signal, 0, AA_MAY_READ, 0, dfaflags)) goto out; if (kernel_supports_ptrace && !prof->policy.rules->add_rule(mediates_ptrace, 0, AA_MAY_READ, 0, dfaflags)) goto out; if (kernel_supports_unix && (!prof->policy.rules->add_rule(mediates_extended_net, 0, AA_MAY_READ, 0, dfaflags) || !prof->policy.rules->add_rule(mediates_net_unix, 0, AA_MAY_READ, 0, dfaflags))) goto out; if (prof->policy.rules->rule_count > 0) { int xmatch_len = 0; prof->policy.dfa = prof->policy.rules->create_dfa(&prof->policy.size, &xmatch_len, dfaflags); delete prof->policy.rules; prof->policy.rules = NULL; if (!prof->policy.dfa) goto out; } else { delete prof->policy.rules; prof->policy.rules = NULL; } error = 0; out: delete prof->policy.rules; prof->policy.rules = NULL; return error; } #ifdef UNIT_TEST #include "unit_test.h" #define MY_FILTER_TEST(input, expected_str) \ do { \ char *test_string = NULL; \ char *output_string = NULL; \ \ test_string = strdup((input)); \ filter_slashes(test_string); \ asprintf(&output_string, "simple filter / conversion for '%s'\texpected = '%s'\tresult = '%s'", \ (input), (expected_str), test_string); \ MY_TEST(strcmp(test_string, (expected_str)) == 0, output_string); \ \ free(test_string); \ free(output_string); \ } \ while (0) static int test_filter_slashes(void) { int rc = 0; MY_FILTER_TEST("///foo//////f//oo////////////////", "/foo/f/oo/"); MY_FILTER_TEST("/foo/f/oo", "/foo/f/oo"); MY_FILTER_TEST("/", "/"); MY_FILTER_TEST("", ""); /* tests for "//" namespace */ MY_FILTER_TEST("//usr", "//usr"); MY_FILTER_TEST("//", "//"); /* tests for not "//" namespace */ MY_FILTER_TEST("///usr", "/usr"); MY_FILTER_TEST("///", "/"); MY_FILTER_TEST("/a/", "/a/"); return rc; } #define MY_REGEX_EXT_TEST(glob, input, expected_str, expected_type) \ do { \ std::string tbuf; \ std::string tbuf2 = "testprefix"; \ char *output_string = NULL; \ std::string expected_str2; \ pattern_t ptype; \ int pos; \ \ ptype = convert_aaregex_to_pcre((input), 0, glob, tbuf, &pos); \ asprintf(&output_string, "simple regex conversion for '%s'\texpected = '%s'\tresult = '%s'", \ (input), (expected_str), tbuf.c_str()); \ MY_TEST(strcmp(tbuf.c_str(), (expected_str)) == 0, output_string); \ MY_TEST(ptype == (expected_type), "simple regex conversion type check for '" input "'"); \ free(output_string); \ /* ensure convert_aaregex_to_pcre appends only to passed ref string */ \ expected_str2 = tbuf2; \ expected_str2.append((expected_str)); \ ptype = convert_aaregex_to_pcre((input), 0, glob, tbuf2, &pos); \ asprintf(&output_string, "simple regex conversion %sfor '%s'\texpected = '%s'\tresult = '%s'", \ glob == glob_null ? "with null allowed in glob " : "",\ (input), expected_str2.c_str(), tbuf2.c_str()); \ MY_TEST((tbuf2 == expected_str2), output_string); \ free(output_string); \ } \ while (0) #define MY_REGEX_TEST(input, expected_str, expected_type) MY_REGEX_EXT_TEST(glob_default, input, expected_str, expected_type) #define MY_REGEX_FAIL_TEST(input) \ do { \ std::string tbuf; \ pattern_t ptype; \ int pos; \ \ ptype = convert_aaregex_to_pcre((input), 0, glob_default, tbuf, &pos); \ MY_TEST(ptype == ePatternInvalid, "simple regex conversion invalid type check for '" input "'"); \ } \ while (0) static int test_aaregex_to_pcre(void) { int rc = 0; MY_REGEX_TEST("/most/basic/test", "/most/basic/test", ePatternBasic); MY_REGEX_FAIL_TEST("\\"); MY_REGEX_TEST("\\\\", "\\\\", ePatternBasic); MY_REGEX_TEST("\\blort", "blort", ePatternBasic); MY_REGEX_TEST("\\\\blort", "\\\\blort", ePatternBasic); MY_REGEX_FAIL_TEST("blort\\"); MY_REGEX_TEST("blort\\\\", "blort\\\\", ePatternBasic); MY_REGEX_TEST("*", "[^/\\x00]*", ePatternRegex); MY_REGEX_TEST("blort*", "blort[^/\\x00]*", ePatternRegex); MY_REGEX_TEST("*blort", "[^/\\x00]*blort", ePatternRegex); MY_REGEX_TEST("\\*", "\\*", ePatternBasic); MY_REGEX_TEST("blort\\*", "blort\\*", ePatternBasic); MY_REGEX_TEST("\\*blort", "\\*blort", ePatternBasic); /* simple quoting */ MY_REGEX_TEST("\\[", "\\[", ePatternBasic); MY_REGEX_TEST("\\]", "\\]", ePatternBasic); MY_REGEX_TEST("\\?", "?", ePatternBasic); MY_REGEX_TEST("\\{", "\\{", ePatternBasic); MY_REGEX_TEST("\\}", "\\}", ePatternBasic); MY_REGEX_TEST("\\,", ",", ePatternBasic); MY_REGEX_TEST("^", "\\^", ePatternBasic); MY_REGEX_TEST("$", "\\$", ePatternBasic); MY_REGEX_TEST(".", "\\.", ePatternBasic); MY_REGEX_TEST("+", "\\+", ePatternBasic); MY_REGEX_TEST("|", "\\|", ePatternBasic); MY_REGEX_TEST("(", "\\(", ePatternBasic); MY_REGEX_TEST(")", "\\)", ePatternBasic); MY_REGEX_TEST("\\^", "\\^", ePatternBasic); MY_REGEX_TEST("\\$", "\\$", ePatternBasic); MY_REGEX_TEST("\\.", "\\.", ePatternBasic); MY_REGEX_TEST("\\+", "\\+", ePatternBasic); MY_REGEX_TEST("\\|", "\\|", ePatternBasic); MY_REGEX_TEST("\\(", "\\(", ePatternBasic); MY_REGEX_TEST("\\)", "\\)", ePatternBasic); /* simple character class tests */ MY_REGEX_TEST("[blort]", "[blort]", ePatternRegex); MY_REGEX_FAIL_TEST("[blort"); MY_REGEX_FAIL_TEST("b[lort"); MY_REGEX_FAIL_TEST("blort["); MY_REGEX_FAIL_TEST("blort]"); MY_REGEX_FAIL_TEST("blo]rt"); MY_REGEX_FAIL_TEST("]blort"); MY_REGEX_TEST("b[lor]t", "b[lor]t", ePatternRegex); /* simple alternation tests */ MY_REGEX_TEST("{alpha,beta}", "(alpha|beta)", ePatternRegex); MY_REGEX_TEST("baz{alpha,beta}blort", "baz(alpha|beta)blort", ePatternRegex); MY_REGEX_FAIL_TEST("{beta}"); MY_REGEX_FAIL_TEST("biz{beta"); MY_REGEX_FAIL_TEST("biz}beta"); MY_REGEX_FAIL_TEST("biz{be,ta"); MY_REGEX_FAIL_TEST("biz,be}ta"); MY_REGEX_FAIL_TEST("biz{}beta"); /* nested alternations */ MY_REGEX_TEST("{{alpha,blort,nested},beta}", "((alpha|blort|nested)|beta)", ePatternRegex); MY_REGEX_FAIL_TEST("{{alpha,blort,nested}beta}"); MY_REGEX_TEST("{{alpha,{blort,nested}},beta}", "((alpha|(blort|nested))|beta)", ePatternRegex); MY_REGEX_TEST("{{alpha,alpha{blort,nested}}beta,beta}", "((alpha|alpha(blort|nested))beta|beta)", ePatternRegex); MY_REGEX_TEST("{{alpha,alpha{blort,nested}}beta,beta}", "((alpha|alpha(blort|nested))beta|beta)", ePatternRegex); MY_REGEX_TEST("{{a,b{c,d}}e,{f,{g,{h{i,j,k},l}m},n}o}", "((a|b(c|d))e|(f|(g|(h(i|j|k)|l)m)|n)o)", ePatternRegex); /* max nesting depth = 50 */ MY_REGEX_TEST("{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a,b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b}b,blort}", "(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a(a|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)|b)b|blort)", ePatternRegex); MY_REGEX_FAIL_TEST("{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a,b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b},b}b,blort}"); /* simple single char */ MY_REGEX_TEST("blor?t", "blor[^/\\x00]t", ePatternRegex); /* simple globbing */ MY_REGEX_TEST("/*", "/[^/\\x00][^/\\x00]*", ePatternRegex); MY_REGEX_TEST("/blort/*", "/blort/[^/\\x00][^/\\x00]*", ePatternRegex); MY_REGEX_TEST("/*/blort", "/[^/\\x00][^/\\x00]*/blort", ePatternRegex); MY_REGEX_TEST("/*/", "/[^/\\x00][^/\\x00]*/", ePatternRegex); MY_REGEX_TEST("/**", "/[^/\\x00][^\\x00]*", ePatternTailGlob); MY_REGEX_TEST("/blort/**", "/blort/[^/\\x00][^\\x00]*", ePatternTailGlob); MY_REGEX_TEST("/**/blort", "/[^/\\x00][^\\x00]*/blort", ePatternRegex); MY_REGEX_TEST("/**/", "/[^/\\x00][^\\x00]*/", ePatternRegex); /* more complicated quoting */ MY_REGEX_FAIL_TEST("\\\\["); MY_REGEX_FAIL_TEST("\\\\]"); MY_REGEX_TEST("\\\\?", "\\\\[^/\\x00]", ePatternRegex); MY_REGEX_FAIL_TEST("\\\\{"); MY_REGEX_FAIL_TEST("\\\\}"); MY_REGEX_TEST("\\\\,", "\\\\,", ePatternBasic); MY_REGEX_TEST("\\\\^", "\\\\\\^", ePatternBasic); MY_REGEX_TEST("\\\\$", "\\\\\\$", ePatternBasic); MY_REGEX_TEST("\\\\.", "\\\\\\.", ePatternBasic); MY_REGEX_TEST("\\\\+", "\\\\\\+", ePatternBasic); MY_REGEX_TEST("\\\\|", "\\\\\\|", ePatternBasic); MY_REGEX_TEST("\\\\(", "\\\\\\(", ePatternBasic); MY_REGEX_TEST("\\\\)", "\\\\\\)", ePatternBasic); MY_REGEX_TEST("\\000", "\\000", ePatternBasic); MY_REGEX_TEST("\\x00", "\\x00", ePatternBasic); MY_REGEX_TEST("\\d000", "\\d000", ePatternBasic); /* more complicated character class tests */ /* -- embedded alternations */ MY_REGEX_TEST("b[\\lor]t", "b[lor]t", ePatternRegex); MY_REGEX_TEST("b[{a,b}]t", "b[{a,b}]t", ePatternRegex); MY_REGEX_TEST("{alpha,b[{a,b}]t,gamma}", "(alpha|b[{a,b}]t|gamma)", ePatternRegex); /* pcre will ignore the '\' before '\{', but it should be okay * for us to pass this on to pcre as '\{' */ MY_REGEX_TEST("b[\\{a,b\\}]t", "b[\\{a,b\\}]t", ePatternRegex); MY_REGEX_TEST("{alpha,b[\\{a,b\\}]t,gamma}", "(alpha|b[\\{a,b\\}]t|gamma)", ePatternRegex); MY_REGEX_TEST("{alpha,b[\\{a\\,b\\}]t,gamma}", "(alpha|b[\\{a\\,b\\}]t|gamma)", ePatternRegex); /* test different globbing behavior conversion */ MY_REGEX_EXT_TEST(glob_default, "/foo/**", "/foo/[^/\\x00][^\\x00]*", ePatternTailGlob); MY_REGEX_EXT_TEST(glob_null, "/foo/**", "/foo/[^/].*", ePatternTailGlob); MY_REGEX_EXT_TEST(glob_default, "/foo/f**", "/foo/f[^\\x00]*", ePatternTailGlob); MY_REGEX_EXT_TEST(glob_null, "/foo/f**", "/foo/f.*", ePatternTailGlob); MY_REGEX_EXT_TEST(glob_default, "/foo/*", "/foo/[^/\\x00][^/\\x00]*", ePatternRegex); MY_REGEX_EXT_TEST(glob_null, "/foo/*", "/foo/[^/][^/]*", ePatternRegex); MY_REGEX_EXT_TEST(glob_default, "/foo/f*", "/foo/f[^/\\x00]*", ePatternRegex); MY_REGEX_EXT_TEST(glob_null, "/foo/f*", "/foo/f[^/]*", ePatternRegex); MY_REGEX_EXT_TEST(glob_default, "/foo/**.ext", "/foo/[^\\x00]*\\.ext", ePatternRegex); MY_REGEX_EXT_TEST(glob_null, "/foo/**.ext", "/foo/.*\\.ext", ePatternRegex); MY_REGEX_EXT_TEST(glob_default, "/foo/f**.ext", "/foo/f[^\\x00]*\\.ext", ePatternRegex); MY_REGEX_EXT_TEST(glob_null, "/foo/f**.ext", "/foo/f.*\\.ext", ePatternRegex); MY_REGEX_EXT_TEST(glob_default, "/foo/*.ext", "/foo/[^/\\x00]*\\.ext", ePatternRegex); MY_REGEX_EXT_TEST(glob_null, "/foo/*.ext", "/foo/[^/]*\\.ext", ePatternRegex); MY_REGEX_EXT_TEST(glob_default, "/foo/f*.ext", "/foo/f[^/\\x00]*\\.ext", ePatternRegex); MY_REGEX_EXT_TEST(glob_null, "/foo/f*.ext", "/foo/f[^/]*\\.ext", ePatternRegex); return rc; } int main(void) { int rc = 0; int retval; retval = test_filter_slashes(); if (retval != 0) rc = retval; retval = test_aaregex_to_pcre(); if (retval != 0) rc = retval; return rc; } #endif /* UNIT_TEST */ apparmor-2.13.3/parser/parser_include.h0000644000175000017500000000233413502024172015653 0ustar jjjj/* * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 * NOVELL (All rights reserved) * Copyright (c) 2010 - 2012 * Canonical Ltd. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Canonical, Ltd. */ #ifndef PARSER_INCLUDE_H #define PARSER_INCLUDE_H extern int preprocess_only; extern int add_search_dir(const char *dir); extern void init_base_dir(void); extern void set_base_dir(char *dir); extern void parse_default_paths(void); extern int do_include_preprocessing(char *profilename); FILE *search_path(char *filename, char **fullpath); extern void push_include_stack(char *filename); extern void pop_include_stack(void); extern void reset_include_stack(const char *filename); #endif apparmor-2.13.3/parser/parser.conf0000644000175000017500000000264713502024172014655 0ustar jjjj# parser.conf is a global AppArmor config file for the apparmor_parser # # It can be used to specify the default options for the parser, which # can then be overriden by options passed on the command line. # # Leading whitespace is ignored and lines that begin with # are treated # as comments. # # Config options are specified one per line using the same format as the # longform command line options (without the preceding --). # # If a value is specified twice the last version to appear is used. ## Suppress Warnings #quiet ## Be verbose #verbose ## Set additional include path #Include /etc/apparmor.d/ # or #Include /usr/share/apparmor ## Set location of apparmor filesystem #subdomainfs /sys/kernel/security/apparmor ## Set match-string to use - for forcing compiler to treat different kernels ## the same # match-string "pattern=aadfa audit perms=crwxamlk/ user::other" ## Turn creating/updating of the cache on by default #write-cache ## Show cache hits #show-cache ## skip cached policy #skip-cache ## skip reading cache but allow updating #skip-read-cache #### Set Optimizaions. Multiple Optimizations can be set, one per line #### # For supported optimizations see # apparmor_parser --help=O ## Turn on equivalence classes #equiv ## Turn off expr tree simplification #Optimize=no-expr-simplify ## Turn off DFA minimization #Optimize=no-minimize ## Adjust compression #Optimize=compress-small #Optimize=compress-fast apparmor-2.13.3/parser/apparmor.d.50000644000175000017500000020740113502024374014642 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "APPARMOR.D 5" .TH APPARMOR.D 5 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" apparmor.d \- syntax of security profiles for AppArmor. .SH "DESCRIPTION" .IX Header "DESCRIPTION" AppArmor profiles describe mandatory access rights granted to given programs and are fed to the AppArmor policy enforcement module using \&\fIapparmor_parser\fR\|(8). This man page describes the format of the AppArmor configuration files; see \fIapparmor\fR\|(7) for an overview of AppArmor. .SH "FORMAT" .IX Header "FORMAT" The following is a BNF-style description of AppArmor policy configuration files; see below for an example AppArmor policy file. AppArmor configuration files are line-oriented; \fB#\fR introduces a comment, similar to shell scripting languages. The exception to this rule is that \fB#include\fR will \fIinclude\fR the contents of a file inline to the policy; this behaviour is modelled after \fIcpp\fR\|(1). .Sp .RS 4 \&\fB\s-1PROFILE FILE\s0\fR = ( [ \fI\s-1PREAMBLE\s0\fR ] [ \fI\s-1PROFILE\s0\fR ] )* .Sp \&\fB\s-1PREAMBLE\s0\fR = ( \fI\s-1COMMENT\s0\fR | \fI\s-1VARIABLE ASSIGNMENT\s0\fR | \fI\s-1ALIAS RULE\s0\fR | \fI\s-1INCLUDE\s0\fR )* Variable assignment and alias rules must come before the profile. .Sp \&\fB\s-1VARIABLE ASSIGNMENT\s0\fR = \fI\s-1VARIABLE\s0\fR ('=' | '+=') (space separated values) .Sp \&\fB\s-1VARIABLE\s0\fR = '@{' \fI\s-1ALPHA\s0\fR [ ( \fI\s-1ALPHANUMERIC\s0\fR | '_' ) ... ] '}' .Sp \&\fB\s-1ALIAS RULE\s0\fR = 'alias' \fI\s-1ABS PATH\s0\fR '\->' \fI\s-1REWRITTEN ABS PATH\s0\fR ',' .Sp \&\fB\s-1INCLUDE\s0\fR = ( '#include' | 'include' ) [ 'if exists' ] ( \fI\s-1ABS PATH\s0\fR | \fI\s-1MAGIC PATH\s0\fR ) .Sp \&\fB\s-1ABS PATH\s0\fR = '\*(L"' path '\*(R"' (the path is passed to \fIopen\fR\|(2)) .Sp \&\fB\s-1MAGIC PATH\s0\fR = '<' relative path '>' The path is relative to \fI/etc/apparmor.d/\fR. .Sp \&\fB\s-1COMMENT\s0\fR = '#' \fI\s-1TEXT\s0\fR [ '\er' ] '\en' .Sp \&\fB\s-1TEXT\s0\fR = any characters .Sp \&\fB\s-1PROFILE\s0\fR = ( \fI\s-1PROFILE HEAD\s0\fR ) [ \fI\s-1ATTACHMENT SPECIFICATION\s0\fR ] [ \fI\s-1PROFILE FLAG CONDS\s0\fR ] '{' ( \fI\s-1RULES\s0\fR )* '}' .Sp \&\fB\s-1PROFILE HEAD\s0\fR = [ 'profile' ] \fI\s-1FILEGLOB\s0\fR | 'profile' \fI\s-1PROFILE NAME\s0\fR .Sp \&\fB\s-1PROFILE NAME\s0\fR ( \fI\s-1UNQUOTED PROFILE NAME\s0\fR | \fI\s-1QUOTED PROFILE NAME\s0\fR ) .Sp \&\fB\s-1QUOTED PROFILE NAME\s0\fR = '"' \fI\s-1UNQUOTED PROFILE NAME\s0\fR '"' .Sp \&\fB\s-1UNQUOTED PROFILE NAME\s0\fR = (must start with alphanumeric character (after variable expansion), or '/' \fB\s-1AARE\s0\fR have special meanings; see below. May include \fI\s-1VARIABLE\s0\fR. Rules with embedded spaces or tabs must be quoted.) .Sp \&\fB\s-1ATTACHMENT SPECIFICATION\s0\fR = \fI\s-1FILEGLOB\s0\fR .Sp \&\fB\s-1PROFILE FLAG CONDS\s0\fR = [ 'flags=' ] '(' comma or white space separated list of \fI\s-1PROFILE FLAGS\s0\fR ')' .Sp \&\fB\s-1PROFILE FLAGS\s0\fR = 'complain' | 'audit' | 'enforce' | 'mediate_deleted' | 'attach_disconnected' | 'chroot_relative' .Sp \&\fB\s-1RULES\s0\fR = [ ( \fI\s-1LINE RULES\s0\fR | \fI\s-1COMMA RULES\s0\fR ',' | \fI\s-1BLOCK RULES\s0\fR ) .Sp \&\fB\s-1LINE RULES\s0\fR = ( \fI\s-1COMMENT\s0\fR | \fI\s-1INCLUDE\s0\fR ) [ '\er' ] '\en' .Sp \&\fB\s-1COMMA RULES\s0\fR = ( \fI\s-1CAPABILITY RULE\s0\fR | \fI\s-1NETWORK RULE\s0\fR | \fI\s-1MOUNT RULE\s0\fR | \fI\s-1PIVOT ROOT RULE\s0\fR | \fI\s-1UNIX RULE\s0\fR | \fI\s-1FILE RULE\s0\fR | \fI\s-1LINK RULE\s0\fR | \fI\s-1CHANGE_PROFILE RULE\s0\fR | \fI\s-1RLIMIT RULE\s0\fR | \fI\s-1DBUS RULE\s0\fR ) .Sp \&\fB\s-1BLOCK RULES\s0\fR = ( \fI\s-1SUBPROFILE\s0\fR | \fI\s-1HAT\s0\fR | \fI\s-1QUALIFIER BLOCK\s0\fR ) .Sp \&\fB\s-1SUBPROFILE\s0\fR = 'profile' \fI\s-1PROFILE NAME\s0\fR [ \fI\s-1ATTACHMENT SPECIFICATION\s0\fR ] [ \fI\s-1PROFILE FLAG CONDS\s0\fR ] '{' ( \fI\s-1RULES\s0\fR )* '}' .Sp \&\fB\s-1HAT\s0\fR = ('hat' | '^') \fI\s-1HATNAME\s0\fR [ \fI\s-1PROFILE FLAG CONDS\s0\fR ] '{' ( \fI\s-1RULES\s0\fR )* '}' .Sp \&\fB\s-1HATNAME\s0\fR = (must start with alphanumeric character. See \fIaa_change_hat\fR\|(2) for a description of how this \*(L"hat\*(R" is used. If '^' is used to start a hat then there is no space between the '^' and \fI\s-1HATNAME\s0\fR) .Sp \&\fB\s-1QUALIFIER BLOCK\s0\fR = \fI\s-1QUALIFIERS\s0\fR \fI\s-1BLOCK\s0\fR .Sp \&\fB\s-1ACCESS TYPE\s0\fR = ( 'allow' | 'deny' ) .Sp \&\fB\s-1QUALIFIERS\s0\fR = [ 'audit' ] [ \fI\s-1ACCESS TYPE\s0\fR ] .Sp \&\fB\s-1CAPABILITY RULE\s0\fR = [ \fI\s-1QUALIFIERS\s0\fR ] 'capability' [ \fI\s-1CAPABILITY LIST\s0\fR ] .Sp \&\fB\s-1CAPABILITY LIST\s0\fR = ( \fI\s-1CAPABILITY\s0\fR )+ .Sp \&\fB\s-1CAPABILITY\s0\fR = (lowercase capability name without '\s-1CAP_\s0' prefix; see \&\fIcapabilities\fR\|(7)) .Sp \&\fB\s-1NETWORK RULE\s0\fR = [ \fI\s-1QUALIFIERS\s0\fR ] 'network' [ \fI\s-1DOMAIN\s0\fR ] [ \fI\s-1TYPE\s0\fR | \fI\s-1PROTOCOL\s0\fR ] .Sp \&\fB\s-1DOMAIN\s0\fR = ( 'unix' | 'inet' | 'ax25' | 'ipx' | 'appletalk' | 'netrom' | 'bridge' | 'atmpvc' | 'x25' | 'inet6' | 'rose' | 'netbeui' | 'security' | 'key' | 'netlink' | 'packet' | 'ash' | 'econet' | 'atmsvc' | 'rds' | 'sna' | 'irda' | 'pppox' | 'wanpipe' | 'llc' | 'ib' | 'mpls' | 'can' | 'tipc' | 'bluetooth' | 'iucv' | 'rxrpc' | 'isdn' | 'phonet' | 'ieee802154' | 'caif' | 'alg' | 'nfc' | 'vsock' | 'kcm' | 'qipcrtr' | 'smc' | 'xdp' ) ',' .Sp \&\fB\s-1TYPE\s0\fR = ( 'stream' | 'dgram' | 'seqpacket' | 'rdm' | 'raw' | 'packet' ) .Sp \&\fB\s-1PROTOCOL\s0\fR = ( 'tcp' | 'udp' | 'icmp' ) .Sp \&\fB\s-1MOUNT RULE\s0\fR = ( \fI\s-1MOUNT\s0\fR | \fI\s-1REMOUNT\s0\fR | \fI\s-1UMOUNT\s0\fR ) .Sp \&\fB\s-1MOUNT\s0\fR = [ \fI\s-1QUALIFIERS\s0\fR ] 'mount' [ \fI\s-1MOUNT CONDITIONS\s0\fR ] [ \fI\s-1SOURCE FILEGLOB\s0\fR ] [ '\->' [ \fI\s-1MOUNTPOINT FILEGLOB\s0\fR ] .Sp \&\fB\s-1REMOUNT\s0\fR = [ \fI\s-1QUALIFIERS\s0\fR ] 'remount' [ \fI\s-1MOUNT CONDITIONS\s0\fR ] \fI\s-1MOUNTPOINT FILEGLOB\s0\fR .Sp \&\fB\s-1UMOUNT\s0\fR = [ \fI\s-1QUALIFIERS\s0\fR ] 'umount' [ \fI\s-1MOUNT CONDITIONS\s0\fR ] \fI\s-1MOUNTPOINT FILEGLOB\s0\fR .Sp \&\fB\s-1MOUNT CONDITIONS\s0\fR = [ ( 'fstype' | 'vfstype' ) ( '=' | 'in' ) \fI\s-1MOUNT FSTYPE EXPRESSION\s0\fR ] [ 'options' ( '=' | 'in' ) \fI\s-1MOUNT FLAGS EXPRESSION\s0\fR ] .Sp \&\fB\s-1MOUNT FSTYPE EXPRESSION\s0\fR = ( \fI\s-1MOUNT FSTYPE LIST\s0\fR | \fI\s-1MOUNT EXPRESSION\s0\fR ) .Sp \&\fB\s-1MOUNT FSTYPE LIST\s0\fR = Comma separated list of valid filesystem and virtual filesystem types (eg ext4, debugfs, devfs, etc) .Sp \&\fB\s-1MOUNT FLAGS EXPRESSION\s0\fR = ( \fI\s-1MOUNT FLAGS LIST\s0\fR | \fI\s-1MOUNT EXPRESSION\s0\fR ) .Sp \&\fB\s-1MOUNT FLAGS LIST\s0\fR = Comma separated list of \fI\s-1MOUNT FLAGS\s0\fR. .Sp \&\fB\s-1MOUNT FLAGS\s0\fR = ( 'ro' | 'rw' | 'nosuid' | 'suid' | 'nodev' | 'dev' | 'noexec' | 'exec' | 'sync' | 'async' | 'remount' | 'mand' | 'nomand' | 'dirsync' | 'noatime' | 'atime' | 'nodiratime' | 'diratime' | 'bind' | 'rbind' | 'move' | 'verbose' | 'silent' | 'loud' | 'acl' | 'noacl' | 'unbindable' | 'runbindable' | 'private' | 'rprivate' | 'slave' | 'rslave' | 'shared' | 'rshared' | 'relatime' | 'norelatime' | 'iversion' | 'noiversion' | 'strictatime' | 'nouser' | 'user' ) .Sp \&\fB\s-1MOUNT EXPRESSION\s0\fR = ( \fI\s-1ALPHANUMERIC\s0\fR | \fI\s-1AARE\s0\fR ) ... .Sp \&\fB\s-1PIVOT ROOT RULE\s0\fR = [ \fI\s-1QUALIFIERS\s0\fR ] pivot_root [ oldroot=\fI\s-1OLD PUT FILEGLOB\s0\fR ] [ \fI\s-1NEW ROOT FILEGLOB\s0\fR ] [ '\->' \fI\s-1PROFILE NAME\s0\fR ] .Sp \&\fB\s-1SOURCE FILEGLOB\s0\fR = \fI\s-1FILEGLOB\s0\fR .Sp \&\fB\s-1MOUNTPOINT FILEGLOB\s0\fR = \fI\s-1FILEGLOB\s0\fR .Sp \&\fB\s-1OLD PUT FILEGLOB\s0\fR = \fI\s-1FILEGLOB\s0\fR .Sp \&\fB\s-1PTRACE_RULE\s0\fR = [ \fI\s-1QUALIFIERS\s0\fR ] 'ptrace' [ \fI\s-1PTRACE ACCESS PERMISSIONS\s0\fR ] [ \fI\s-1PTRACE PEER\s0\fR ] .Sp \&\fB\s-1PTRACE ACCESS PERMISSIONS\s0\fR = \fI\s-1PTRACE ACCESS\s0\fR | \fI\s-1PTRACE ACCESS LIST\s0\fR .Sp \&\fB\s-1PTRACE ACCESS LIST\s0\fR = '(' Comma or space separated list of \fI\s-1PTRACE ACCESS\s0\fR ')' .Sp \&\fB\s-1PTRACE ACCESS\s0\fR = ( 'r' | 'w' | 'rw' | 'read' | 'readby' | 'trace' | 'tracedby' ) .Sp \&\fB\s-1PTRACE PEER\s0\fR = 'peer' '=' \fI\s-1AARE\s0\fR .Sp \&\fB\s-1SIGNAL_RULE\s0\fR = [ \fI\s-1QUALIFIERS\s0\fR ] 'signal' [ \fI\s-1SIGNAL ACCESS PERMISSIONS\s0\fR ] [ \fI\s-1SIGNAL SET\s0\fR ] [ \fI\s-1SIGNAL PEER\s0\fR ] .Sp \&\fB\s-1SIGNAL ACCESS PERMISSIONS\s0\fR = \fI\s-1SIGNAL ACCESS\s0\fR | \fI\s-1SIGNAL ACCESS LIST\s0\fR .Sp \&\fB\s-1SIGNAL ACCESS LIST\s0\fR = '(' Comma or space separated list of \fI\s-1SIGNAL ACCESS\s0\fR ')' .Sp \&\fB\s-1SIGNAL ACCESS\s0\fR = ( 'r' | 'w' | 'rw' | 'read' | 'write' | 'send' | 'receive' ) .Sp \&\fB\s-1SIGNAL SET\s0\fR = 'set' '=' '(' \fI\s-1SIGNAL LIST\s0\fR ')' .Sp \&\fB\s-1SIGNAL LIST\s0\fR = Comma or space separated list of \fI\s-1SIGNALS\s0\fR .Sp \&\fB\s-1SIGNALS\s0\fR = ( 'hup' | 'int' | 'quit' | 'ill' | 'trap' | 'abrt' | 'bus' | 'fpe' | 'kill' | 'usr1' | 'segv' | 'usr2' | 'pipe' | 'alrm' | 'term' | 'stkflt' | 'chld' | 'cont' | 'stop' | 'stp' | 'ttin' | 'ttou' | 'urg' | 'xcpu' | 'xfsz' | 'vtalrm' | 'prof' | 'winch' | 'io' | 'pwr' | 'sys' | 'emt' | 'exists' | 'rtmin+0' ... 'rtmin+32' ) .Sp \&\fB\s-1SIGNAL PEER\s0\fR = 'peer' '=' \fI\s-1AARE\s0\fR .Sp \&\fB\s-1DBUS RULE\s0\fR = ( \fI\s-1DBUS MESSAGE RULE\s0\fR | \fI\s-1DBUS SERVICE RULE\s0\fR | \fI\s-1DBUS EAVESDROP RULE\s0\fR | \fI\s-1DBUS COMBINED RULE\s0\fR ) .Sp \&\fB\s-1DBUS MESSAGE RULE\s0\fR = [ \fI\s-1QUALIFIERS\s0\fR ] 'dbus' [ \fI\s-1DBUS ACCESS EXPRESSION\s0\fR ] [ \fI\s-1DBUS BUS\s0\fR ] [ \fI\s-1DBUS PATH\s0\fR ] [ \fI\s-1DBUS INTERFACE\s0\fR ] [ \fI\s-1DBUS MEMBER\s0\fR ] [ \fI\s-1DBUS PEER\s0\fR ] .Sp \&\fB\s-1DBUS SERVICE RULE\s0\fR = [ \fI\s-1QUALIFIERS\s0\fR ] 'dbus' [ \fI\s-1DBUS ACCESS EXPRESSION\s0\fR ] [ \fI\s-1DBUS BUS\s0\fR ] [ \fI\s-1DBUS NAME\s0\fR ] .Sp \&\fB\s-1DBUS EAVESDROP RULE\s0\fR = [ \fI\s-1QUALIFIERS\s0\fR ] 'dbus' [ \fI\s-1DBUS ACCESS EXPRESSION\s0\fR ] [ \fI\s-1DBUS BUS\s0\fR ] .Sp \&\fB\s-1DBUS COMBINED RULE\s0\fR = [ \fI\s-1QUALIFIERS\s0\fR ] 'dbus' [ \fI\s-1DBUS ACCESS EXPRESSION\s0\fR ] [ \fI\s-1DBUS BUS\s0\fR ] .Sp \&\fB\s-1DBUS ACCESS EXPRESSION\s0\fR = ( \fI\s-1DBUS ACCESS\s0\fR | '(' \fI\s-1DBUS ACCESS LIST\s0\fR ')' ) .Sp \&\fB\s-1DBUS BUS\s0\fR = 'bus' '=' '(' 'system' | 'session' | '"' \fI\s-1AARE\s0\fR '"' | \fI\s-1AARE\s0\fR ')' .Sp \&\fB\s-1DBUS PATH\s0\fR = 'path' '=' '(' '"' \fI\s-1AARE\s0\fR '"' | \fI\s-1AARE\s0\fR ')' .Sp \&\fB\s-1DBUS INTERFACE\s0\fR = 'interface' '=' '(' '"' \fI\s-1AARE\s0\fR '"' | \fI\s-1AARE\s0\fR ')' .Sp \&\fB\s-1DBUS MEMBER\s0\fR = 'member' '=' '(' '"' \fI\s-1AARE\s0\fR '"' | \fI\s-1AARE\s0\fR ')' .Sp \&\fB\s-1DBUS PEER\s0\fR = 'peer' '=' '(' [ \fI\s-1DBUS NAME\s0\fR ] [ \fI\s-1DBUS LABEL\s0\fR ] ')' .Sp \&\fB\s-1DBUS NAME\s0\fR = 'name' '=' '(' '"' \fI\s-1AARE\s0\fR '"' | \fI\s-1AARE\s0\fR ')' .Sp \&\fB\s-1DBUS LABEL\s0\fR = 'label' '=' '(' '"' \fI\s-1AARE\s0\fR '"' | \fI\s-1AARE\s0\fR ')' .Sp \&\fB\s-1DBUS ACCESS LIST\s0\fR = Comma separated list of \fI\s-1DBUS ACCESS\s0\fR .Sp \&\fB\s-1DBUS ACCESS\s0\fR = ( 'send' | 'receive' | 'bind' | 'eavesdrop' | 'r' | 'read' | 'w' | 'write' | 'rw' ) Some accesses are incompatible with some rules; see below. .Sp \&\fB\s-1AARE\s0\fR = \fB?*[]{}^\fR See below for meanings. .Sp \&\fB\s-1UNIX RULE\s0\fR = [ \fI\s-1QUALIFIERS\s0\fR ] 'unix' [ \fI\s-1UNIX ACCESS EXPR\s0\fR ] [ \fI\s-1UNIX RULE CONDS\s0\fR ] [ \fI\s-1UNIX LOCAL EXPR\s0\fR ] [ \fI\s-1UNIX PEER EXPR\s0\fR ] .Sp \&\fB\s-1UNIX ACCESS EXPR\s0\fR = ( \fI\s-1UNIX ACCESS\s0\fR | \fI\s-1UNIX ACCESS LIST\s0\fR ) .Sp \&\fB\s-1UNIX ACCESS\s0\fR = ( 'create' | 'bind' | 'listen' | 'accept' | 'connect' | 'shutdown' | 'getattr' | 'setattr' | 'getopt' | 'setopt' | 'send' | 'receive' | 'r' | 'w' | 'rw' ) Some access modes are incompatible with some rules or require additional parameters. .Sp \&\fB\s-1UNIX ACCESS LIST\s0\fR = '(' \fI\s-1UNIX ACCESS\s0\fR ( [','] \fI\s-1UNIX ACCESS\s0\fR )* ')' .Sp \&\fB\s-1UNIX RULE CONDS\s0\fR = ( \fI\s-1TYPE COND\s0\fR | \fI\s-1PROTO COND\s0\fR ) Each cond can appear at most once. .Sp \&\fB\s-1TYPE COND\s0\fR = 'type' '=' ( \fI\s-1AARE\s0\fR | '(' ( '"' \fI\s-1AARE\s0\fR '"' | \fI\s-1AARE\s0\fR )+ ')' ) .Sp \&\fB\s-1PROTO COND\s0\fR = 'protocol' '=' ( \fI\s-1AARE\s0\fR | '(' ( '"' \fI\s-1AARE\s0\fR '"' | \fI\s-1AARE\s0\fR )+ ')' ) .Sp \&\fB\s-1UNIX LOCAL EXPR\s0\fR = ( \fI\s-1UNIX ADDRESS COND\s0\fR | \fI\s-1UNIX LABEL COND\s0\fR | \fI\s-1UNIX ATTR COND\s0\fR | \fI\s-1UNIX OPT COND\s0\fR )* Each cond can appear at most once. .Sp \&\fB\s-1UNIX PEER EXPR\s0\fR = 'peer' '=' ( \fI\s-1UNIX ADDRESS COND\s0\fR | \fI\s-1UNIX LABEL COND\s0\fR )+ Each cond can appear at most once. .Sp \&\fB\s-1UNIX ADDRESS COND\s0\fR 'addr' '=' ( \fI\s-1AARE\s0\fR | '(' '"' \fI\s-1AARE\s0\fR '"' | \fI\s-1AARE\s0\fR ')' ) .Sp \&\fB\s-1UNIX LABEL COND\s0\fR 'label' '=' ( \fI\s-1AARE\s0\fR | '(' '"' \fI\s-1AARE\s0\fR '"' | \fI\s-1AARE\s0\fR ')' ) .Sp \&\fB\s-1UNIX ATTR COND\s0\fR 'attr' '=' ( \fI\s-1AARE\s0\fR | '(' '"' \fI\s-1AARE\s0\fR '"' | \fI\s-1AARE\s0\fR ')' ) .Sp \&\fB\s-1UNIX OPT COND\s0\fR 'opt' '=' ( \fI\s-1AARE\s0\fR | '(' '"' \fI\s-1AARE\s0\fR '"' | \fI\s-1AARE\s0\fR ')' ) .Sp \&\fB\s-1RLIMIT RULE\s0\fR = 'set' 'rlimit' [\fI\s-1RLIMIT\s0\fR '<=' \fI\s-1RLIMIT VALUE\s0\fR ] .Sp \&\fB\s-1RLIMIT\s0\fR = ( 'cpu' | 'fsize' | 'data' | 'stack' | 'core' | 'rss' | 'nofile' | 'ofile' | 'as' | 'nproc' | 'memlock' | 'locks' | 'sigpending' | 'msgqueue' | 'nice' | 'rtprio' | 'rttime' ) .Sp \&\fB\s-1RLIMIT VALUE\s0\fR = ( \fI\s-1RLIMIT SIZE\s0\fR | \fI\s-1RLIMIT NUMBER\s0\fR | \fI\s-1RLIMIT TIME\s0\fR | \fI\s-1RLIMIT NICE\s0\fR ) .Sp \&\fB\s-1RLIMIT SIZE\s0\fR = \fI\s-1NUMBER\s0\fR ( 'K' | 'M' | 'G' ) Only applies to \s-1RLIMIT\s0 of 'fsize', 'data', 'stack', 'core', 'rss', 'as', 'memlock', 'msgqueue'. .Sp \&\fB\s-1RLIMIT NUMBER\s0\fR = number from 0 to max rlimit value. Only applies to \s-1RLIMIT\s0 of 'ofile', 'nofile', 'locks', 'sigpending', 'nproc', 'rtprio'. .Sp \&\fB\s-1RLIMIT TIME\s0\fR = \fI\s-1NUMBER\s0\fR ( 'us' | 'microsecond' | 'microseconds' | 'ms' | 'millisecond' | 'milliseconds' | 's' | 'sec' | 'second' | 'seconds' | 'min' | 'minute' | 'minutes' | 'h' | 'hour' | 'hours' | 'd' | 'day' | 'days' | 'week' | 'weeks' ) Only applies to \s-1RLIMIT\s0 of 'cpu' and 'rttime'. \s-1RLIMIT\s0 'cpu' only allows units >= 'seconds'. .Sp \&\fB\s-1RLIMIT NICE\s0\fR = a number between \-20 and 19. Only applies to \s-1RLIMIT\s0 of 'nice'. .Sp \&\fB\s-1FILE RULE\s0\fR = [ \fI\s-1QUALIFIERS\s0\fR ] [ 'owner' ] ( 'file' | [ 'file' ] ( \fI\s-1FILEGLOB\s0\fR \fI\s-1ACCESS\s0\fR | \fI\s-1ACCESS\s0\fR \fI\s-1FILEGLOB\s0\fR ) [ '\->' \fI\s-1EXEC TARGET\s0\fR ] ) .Sp \&\fB\s-1FILEGLOB\s0\fR = ( \fI\s-1QUOTED FILEGLOB\s0\fR | \fI\s-1UNQUOTED FILEGLOB\s0\fR ) .Sp \&\fB\s-1QUOTED FILEGLOB\s0\fR = '"' \fI\s-1UNQUOTED FILEGLOB\s0\fR '"' .Sp \&\fB\s-1UNQUOTED FILEGLOB\s0\fR = (must start with '/' (after variable expansion), \fB\s-1AARE\s0\fR have special meanings; see below. May include \fI\s-1VARIABLE\s0\fR. Rules with embedded spaces or tabs must be quoted. Rules must end with '/' to apply to directories.) .Sp \&\fB\s-1ACCESS\s0\fR = ( 'r' | 'w' | 'a' | 'l' | 'k' | 'm' | \fI\s-1EXEC TRANSITION\s0\fR )+ (not all combinations are allowed; see below.) .Sp \&\fB\s-1EXEC TRANSITION\s0\fR = ( 'ix' | 'ux' | 'Ux' | 'px' | 'Px' | 'cx' | 'Cx' | 'pix' | 'Pix' | 'cix' | 'Cix' | 'pux' | 'PUx' | 'cux' | 'CUx' | 'x' ) A bare 'x' is only allowed in rules with the deny qualifier, everything else only without the deny qualifier. .Sp \&\fB\s-1EXEC TARGET\s0\fR = name Requires \fI\s-1EXEC TRANSITION\s0\fR specified. .Sp \&\fB\s-1LINK RULE\s0\fR = \fI\s-1QUALIFIERS\s0\fR [ 'owner' ] 'link' [ 'subset' ] \fI\s-1FILEGLOB\s0\fR '\->' \fI\s-1FILEGLOB\s0\fR .Sp \&\fB\s-1ALPHA\s0\fR = ('a', 'b', 'c', ... 'z', 'A', 'B', ... 'Z') .Sp \&\fB\s-1ALPHANUMERIC\s0\fR = ('0', '1', '2', ... '9', 'a', 'b', 'c', ... 'z', 'A', 'B', ... 'Z') .Sp \&\fB\s-1CHANGE_PROFILE RULE\s0\fR = 'change_profile' [ [ \fI\s-1EXEC MODE\s0\fR ] \fI\s-1EXEC COND\s0\fR ] [ '\->' \fI\s-1PROFILE NAME\s0\fR ] .Sp \&\fB\s-1EXEC_MODE\s0\fR = ( 'safe' | 'unsafe' ) .Sp \&\fB\s-1EXEC COND\s0\fR = \fI\s-1FILEGLOB\s0\fR .RE .PP All resources and programs need a full path. There may be any number of subprofiles (aka child profiles) in a profile, limited only by kernel memory. Subprofile names are limited to 974 characters. Child profiles can be used to confine an application in a special way, or when you want the child to be unconfined on the system, but confined when called from the parent. Hats are a special child profile that can be used with the \&\fIaa_change_hat\fR\|(2) \s-1API\s0 call. Applications written or modified to use \&\fIaa_change_hat\fR\|(2) can take advantage of subprofiles to run under different confinements, dependent on program logic. Several \fIaa_change_hat\fR\|(2)\-aware applications exist, including an Apache module, \fImod_apparmor\fR\|(5); a \s-1PAM\s0 module, pam_apparmor; and a Tomcat valve, tomcat_apparmor. Applications written or modified to use \fIchange_profile\fR\|(2) transition permanently to the specified profile. libvirt is one such application. .SS "Access Modes" .IX Subsection "Access Modes" File permission access modes consists of combinations of the following modes: .IP "\fBr\fR" 8 .IX Item "r" \&\- read .IP "\fBw\fR" 8 .IX Item "w" \&\- write \*(-- conflicts with append .IP "\fBa\fR" 8 .IX Item "a" \&\- append \*(-- conflicts with write .IP "\fBux\fR" 8 .IX Item "ux" \&\- unconfined execute .IP "\fBUx\fR" 8 .IX Item "Ux" \&\- unconfined execute \*(-- scrub the environment .IP "\fBpx\fR" 8 .IX Item "px" \&\- discrete profile execute .IP "\fBPx\fR" 8 .IX Item "Px" \&\- discrete profile execute \*(-- scrub the environment .IP "\fBcx\fR" 8 .IX Item "cx" \&\- transition to subprofile on execute .IP "\fBCx\fR" 8 .IX Item "Cx" \&\- transition to subprofile on execute \*(-- scrub the environment .IP "\fBix\fR" 8 .IX Item "ix" \&\- inherit execute .IP "\fBpix\fR" 8 .IX Item "pix" \&\- discrete profile execute with inherit fallback .IP "\fBPix\fR" 8 .IX Item "Pix" \&\- discrete profile execute with inherit fallback \*(-- scrub the environment .IP "\fBcix\fR" 8 .IX Item "cix" \&\- transition to subprofile on execute with inherit fallback .IP "\fBCix\fR" 8 .IX Item "Cix" \&\- transition to subprofile on execute with inherit fallback \*(-- scrub the environment .IP "\fBpux\fR" 8 .IX Item "pux" \&\- discrete profile execute with fallback to unconfined .IP "\fBPUx\fR" 8 .IX Item "PUx" \&\- discrete profile execute with fallback to unconfined \*(-- scrub the environment .IP "\fBcux\fR" 8 .IX Item "cux" \&\- transition to subprofile on execute with fallback to unconfined .IP "\fBCUx\fR" 8 .IX Item "CUx" \&\- transition to subprofile on execute with fallback to unconfined \*(-- scrub the environment .IP "\fBdeny x\fR" 8 .IX Item "deny x" \&\- disallow execute (in rules with the deny qualifier) .IP "\fBm\fR" 8 .IX Item "m" \&\- allow \s-1PROT_EXEC\s0 with \fImmap\fR\|(2) calls .IP "\fBl\fR" 8 .IX Item "l" \&\- link .IP "\fBk\fR" 8 .IX Item "k" \&\- lock .SS "Access Modes Details" .IX Subsection "Access Modes Details" .IP "\fBr \- Read mode\fR" 4 .IX Item "r - Read mode" Allows the program to have read access to the file or directory listing. Read access is required for shell scripts and other interpreted content. .IP "\fBw \- Write mode\fR" 4 .IX Item "w - Write mode" Allows the program to have write access to the file. Files and directories must have this permission if they are to be unlinked (removed.) Write mode is not required on a directory to rename or create files within the directory. .Sp This mode conflicts with append mode. .IP "\fBa \- Append mode\fR" 4 .IX Item "a - Append mode" Allows the program to have a limited appending only write access to the file. Append mode will prevent an application from opening the file for write unless it passes the O_APPEND parameter flag on open. .Sp The mode conflicts with Write mode. .IP "\fBux \- Unconfined execute mode\fR" 4 .IX Item "ux - Unconfined execute mode" Allows the program to execute the program without any AppArmor profile being applied to the program. .Sp This mode is useful when a confined program needs to be able to perform a privileged operation, such as rebooting the machine. By placing the privileged section in another executable and granting unconfined execution rights, it is possible to bypass the mandatory constraints imposed on all confined processes. For more information on what is constrained, see the \fIapparmor\fR\|(7) man page. .Sp \&\fB\s-1WARNING\s0\fR 'ux' should only be used in very special cases. It enables the designated child processes to be run without any AppArmor protection. \&'ux' does not scrub the environment of variables such as \s-1LD_PRELOAD\s0; as a result, the calling domain may have an undue amount of influence over the callee. Use this mode only if the child absolutely must be run unconfined and \s-1LD_PRELOAD\s0 must be used. Any profile using this mode provides negligible security. Use at your own risk. .Sp Incompatible with other exec transition modes and the deny qualifier. .IP "\fBUx \- unconfined execute \*(-- scrub the environment\fR" 4 .IX Item "Ux - unconfined execute scrub the environment" \&'Ux' allows the named program to run in 'ux' mode, but AppArmor will invoke the Linux Kernel's \fBunsafe_exec\fR routines to scrub the environment, similar to setuid programs. (See \fIld.so\fR\|(8) for some information on setuid/setgid environment scrubbing.) .Sp \&\fB\s-1WARNING\s0\fR 'Ux' should only be used in very special cases. It enables the designated child processes to be run without any AppArmor protection. Use this mode only if the child absolutely must be run unconfined. Use at your own risk. .Sp Incompatible with other exec transition modes and the deny qualifier. .IP "\fBpx \- Discrete Profile execute mode\fR" 4 .IX Item "px - Discrete Profile execute mode" This mode requires that a discrete security profile is defined for a program executed and forces an AppArmor domain transition. If there is no profile defined then the access will be denied. .Sp \&\fB\s-1WARNING\s0\fR 'px' does not scrub the environment of variables such as \&\s-1LD_PRELOAD\s0; as a result, the calling domain may have an undue amount of influence over the callee. .Sp Incompatible with other exec transition modes and the deny qualifier. .IP "\fBPx \- Discrete Profile execute mode \*(-- scrub the environment\fR" 4 .IX Item "Px - Discrete Profile execute mode scrub the environment" \&'Px' allows the named program to run in 'px' mode, but AppArmor will invoke the Linux Kernel's \fBunsafe_exec\fR routines to scrub the environment, similar to setuid programs. (See \fIld.so\fR\|(8) for some information on setuid/setgid environment scrubbing.) .Sp Incompatible with other exec transition modes and the deny qualifier. .IP "\fBcx \- Transition to Subprofile execute mode\fR" 4 .IX Item "cx - Transition to Subprofile execute mode" This mode requires that a local security profile is defined and forces an AppArmor domain transition to the named profile. If there is no profile defined then the access will be denied. .Sp \&\fB\s-1WARNING\s0\fR 'cx' does not scrub the environment of variables such as \&\s-1LD_PRELOAD\s0; as a result, the calling domain may have an undue amount of influence over the callee. .Sp Incompatible with other exec transition modes and the deny qualifier. .IP "\fBCx \- Transition to Subprofile execute mode \*(-- scrub the environment\fR" 4 .IX Item "Cx - Transition to Subprofile execute mode scrub the environment" \&'Cx' allows the named program to run in 'cx' mode, but AppArmor will invoke the Linux Kernel's \fBunsafe_exec\fR routines to scrub the environment, similar to setuid programs. (See \fIld.so\fR\|(8) for some information on setuid/setgid environment scrubbing.) .Sp Incompatible with other exec transition modes and the deny qualifier. .IP "\fBix \- Inherit execute mode\fR" 4 .IX Item "ix - Inherit execute mode" Prevent the normal AppArmor domain transition on \fIexecve\fR\|(2) when the profiled program executes the named program. Instead, the executed resource will inherit the current profile. .Sp This mode is useful when a confined program needs to call another confined program without gaining the permissions of the target's profile, or losing the permissions of the current profile. There is no version to scrub the environment because 'ix' executions don't change privileges. .Sp Incompatible with other exec transition modes and the deny qualifier. .IP "\fBProfile transition with inheritance fallback execute mode\fR" 4 .IX Item "Profile transition with inheritance fallback execute mode" These modes attempt to perform a domain transition as specified by the matching permission (shown below) and if that transition fails to find the matching profile the domain transition proceeds using the 'ix' transition mode. .Sp .Vb 4 \& \*(AqPix\*(Aq == \*(AqPx\*(Aq with fallback to \*(Aqix\*(Aq \& \*(Aqpix\*(Aq == \*(Aqpx\*(Aq with fallback to \*(Aqix\*(Aq \& \*(AqCix\*(Aq == \*(AqCx\*(Aq with fallback to \*(Aqix\*(Aq \& \*(Aqcix\*(Aq == \*(Aqcx\*(Aq with fallback to \*(Aqix\*(Aq .Ve .Sp Incompatible with other exec transition modes and the deny qualifier. .IP "\fBProfile transition with unconfined fallback execute mode\fR" 4 .IX Item "Profile transition with unconfined fallback execute mode" These modes attempt to perform a domain transition as specified by the matching permission (shown below) and if that transition fails to find the matching profile the domain transition proceeds using the 'ux' transition mode if 'pux', 'cux' or the 'Ux' transition mode if 'PUx', 'CUx' is used. .Sp .Vb 4 \& \*(AqPUx\*(Aq == \*(AqPx\*(Aq with fallback to \*(AqUx\*(Aq \& \*(Aqpux\*(Aq == \*(Aqpx\*(Aq with fallback to \*(Aqux\*(Aq \& \*(AqCUx\*(Aq == \*(AqCx\*(Aq with fallback to \*(AqUx\*(Aq \& \*(Aqcux\*(Aq == \*(Aqcx\*(Aq with fallback to \*(Aqux\*(Aq .Ve .Sp Incompatible with other exec transition modes and the deny qualifier. .IP "\fBdeny x \- Deny execute\fR" 4 .IX Item "deny x - Deny execute" For rules including the deny modifier, only 'x' is allowed to deny execute. .Sp The 'ix', 'Px', 'px', 'Cx', 'cx' and the fallback modes conflict with the deny modifier. .IP "\fBDirected profile transitions\fR" 4 .IX Item "Directed profile transitions" The directed ('px', 'Px', 'pix', 'Pix', 'pux', 'PUx') profile and subprofile ('cx', 'Cx', 'cix', 'Cix', 'cux', 'CUx') transitions normally determine the profile to transition to from the executable name. It is however possible to specify the name of the profile that the transition should use. .Sp The name of the profile to transition to is specified using the '\->' followed by the name of the profile to transition to. Eg. .Sp .Vb 1 \& /bin/** px \-> profile, .Ve .Sp Incompatible with other exec transition modes. .IP "\fBm \- Allow executable mapping\fR" 4 .IX Item "m - Allow executable mapping" This mode allows a file to be mapped into memory using \fImmap\fR\|(2)'s \&\s-1PROT_EXEC\s0 flag. This flag marks the pages executable; it is used on some architectures to provide non-executable data pages, which can complicate exploit attempts. AppArmor uses this mode to limit which files a well-behaved program (or all programs on architectures that enforce non-executable memory access controls) may use as libraries, to limit the effect of invalid \fB\-L\fR flags given to \fIld\fR\|(1) and \fB\s-1LD_PRELOAD\s0\fR, \&\fB\s-1LD_LIBRARY_PATH\s0\fR, given to \fIld.so\fR\|(8). .IP "\fBl \- Link mode\fR" 4 .IX Item "l - Link mode" Allows the program to be able to create a link with this name. When a link is created, the new link \fB\s-1MUST\s0\fR have a subset of permissions as the original file (with the exception that the destination does not have to have link access.) If there is an 'x' rule on the new link, it must match the original file exactly. .IP "\fBk \- lock mode\fR" 4 .IX Item "k - lock mode" Allows the program to be able lock a file with this name. This permission covers both advisory and mandatory locking. .IP "\fBleading \s-1OR\s0 trailing access permissions\fR" 4 .IX Item "leading OR trailing access permissions" File rules can be specified with the access permission either leading or trailing the file glob. Eg. .Sp .Vb 1 \& rw /**, # leading permissions \& \& /** rw, # trailing permissions .Ve .Sp When leading permissions are used further rule options and context may be allowed, Eg. .Sp .Vb 1 \& l /foo \-> /bar, # lead \*(Aql\*(Aq link permission is equivalent to link rules .Ve .SS "Link rules" .IX Subsection "Link rules" Link rules allow specifying permission to form a hard link as a link target pair. If the subset condition is specified then the permissions to access the link file must be a subset of the profiles permissions to access the target file. If there is an 'x' rule on the new link, it must match the original file exactly. .PP Eg. .PP .Vb 4 \& /file1 r, \& /file2 rwk, \& /link* rw, \& link subset /link* \-> /**, .Ve .PP The link rule allows linking of /link to both /file1 or /file2 by name however because the /link file has 'rw' permissions it is not allowed to link to /file1 because that would grant an access path to /file1 with more permissions than the 'r' permissions the profile specifies. .PP A link of /link to /file2 would be allowed because the 'rw' permissions of /link are a subset of the 'rwk' permissions for /file1. .PP The link rule is equivalent to specifying the 'l' link permission as a leading permission with no other file access permissions. When this is done the link rule options can be specified. .PP The following link rule is equivalent to the 'l' permission file rule .PP .Vb 2 \& link /foo \-> bar, \& l /foo \-> /bar, .Ve .PP File rules that specify the 'l' permission and don't specify the extend link permissions map to link rules as follows. .PP .Vb 3 \& /foo l, \& l /foo, \& link subset /foo \-> /**, .Ve .SS "Comments" .IX Subsection "Comments" Comments start with # and may begin at any place within a line. The comment ends when the line ends. This is the same comment style as shell scripts. .SS "Capabilities" .IX Subsection "Capabilities" The only capabilities a confined process may use may be enumerated; for the complete list, please refer to \fIcapabilities\fR\|(7). Note that granting some capabilities renders AppArmor confinement for that domain advisory; while \fIopen\fR\|(2), \fIread\fR\|(2), \fIwrite\fR\|(2), etc., will still return error when access is not granted, some capabilities allow loading kernel modules, arbitrary access to \s-1IPC,\s0 ability to bypass discretionary access controls, and other operations that are typically reserved for the root user. .SS "Network Rules" .IX Subsection "Network Rules" AppArmor supports simple coarse grained network mediation. The network rule restrict all \fIsocket\fR\|(2) based operations. The mediation done is a course grained check on whether a socket of a given type and family can be created, read, or written. There is no mediation based of port number or protocol beyond tcp, udp, and raw. Network \fInetlink\fR\|(7) rules may only specify type 'dgram' and 'raw'. .PP AppArmor network rules are accumulated so that the granted network permissions are the union of all the listed network rule permissions. .PP AppArmor network rules are broad and general and become more restrictive as further information is specified. .PP eg. .PP .Vb 5 \& network, #allow access to all networking \& network tcp, #allow access to tcp \& network inet tcp, #allow access to tcp only for inet4 addresses \& network inet6 tcp, #allow access to tcp only for inet6 addresses \& network netlink raw, #allow access to AF_NETLINK SOCK_RAW .Ve .SS "Mount Rules" .IX Subsection "Mount Rules" AppArmor supports mount mediation and allows specifying filesystem types and mount flags. The syntax of mount rules in AppArmor is based on the \fImount\fR\|(8) command syntax. Mount rules must contain one of the mount, remount or umount keywords, but all mount conditions are optional. Unspecified optional conditionals are assumed to match all entries (eg, not specifying fstype means all fstypes are matched). Due to the complexity of the mount command and how options may be specified, AppArmor allows specifying conditionals three different ways: .IP "1." 4 If a conditional is specified using '=', then the rule only grants permission for mounts matching the exactly specified options. For example, an AppArmor policy with the following rule: .Sp .Vb 1 \& mount options=ro /dev/foo \-E /mnt/, .Ve .Sp Would match: .Sp .Vb 1 \& $ mount \-o ro /dev/foo /mnt .Ve .Sp but not either of these: .Sp .Vb 1 \& $ mount \-o ro,atime /dev/foo /mnt \& \& $ mount \-o rw /dev/foo /mnt .Ve .IP "2." 4 If a conditional is specified using 'in', then the rule grants permission for mounts matching any combination of the specified options. For example, if an AppArmor policy has the following rule: .Sp .Vb 1 \& mount options in (ro,atime) /dev/foo \-> /mnt/, .Ve .Sp all of these mount commands will match: .Sp .Vb 1 \& $ mount \-o ro /dev/foo /mnt \& \& $ mount \-o ro,atime /dev/foo /mnt \& \& $ mount \-o atime /dev/foo /mnt .Ve .Sp but none of these will: .Sp .Vb 1 \& $ mount \-o ro,sync /dev/foo /mnt \& \& $ mount \-o ro,atime,sync /dev/foo /mnt \& \& $ mount \-o rw /dev/foo /mnt \& \& $ mount \-o rw,noatime /dev/foo /mnt \& \& $ mount /dev/foo /mnt .Ve .IP "3." 4 If multiple conditionals are specified in a single mount rule, then the rule grants permission for each set of options. This provides a shorthand when writing mount rules which might help to logically break up a conditional. For example, if an AppArmor policy has the following rule: .Sp .Vb 1 \& mount options=ro options=atime .Ve .Sp both of these mount commands will match: .Sp .Vb 1 \& $ mount \-o ro /dev/foo /mnt \& \& $ mount \-o atime /dev/foo /mnt .Ve .Sp but this one will not: .Sp .Vb 1 \& $ mount \-o ro,atime /dev/foo /mnt .Ve .PP Note that separate mount rules are distinct and the options do not accumulate. For example, these AppArmor mount rules: .PP .Vb 1 \& mount options=ro, \& \& mount options=atime, .Ve .PP are not equivalent to either of these mount rules: .PP .Vb 1 \& mount options=(ro,atime), \& \& mount options in (ro,atime), .Ve .PP To help clarify the flexibility and complexity of mount rules, here are some example rules with accompanying matching commands: .IP "\fBmount,\fR" 4 .IX Item "mount," the 'mount' rule without any conditionals is the most generic and allows any mount. Equivalent to 'mount fstype=** options=** ** \-> /**'. .IP "\fBmount /dev/foo,\fR" 4 .IX Item "mount /dev/foo," allow mounting of /dev/foo anywhere with any options. Some matching mount commands: .Sp .Vb 1 \& $ mount /dev/foo /mnt \& \& $ mount \-t ext3 /dev/foo /mnt \& \& $ mount \-t vfat /dev/foo /mnt \& \& $ mount \-o ro,atime,noexec,nodiratime /dev/foo /srv/some/mountpoint .Ve .IP "\fBmount options=ro /dev/foo,\fR" 4 .IX Item "mount options=ro /dev/foo," allow mounting of /dev/foo anywhere, as read only. Some matching mount commands: .Sp .Vb 1 \& $ mount \-o ro /dev/foo /mnt \& \& $ mount \-o ro /dev/foo /some/where/else .Ve .IP "\fBmount options=(ro,atime) /dev/foo,\fR" 4 .IX Item "mount options=(ro,atime) /dev/foo," allow mount of /dev/foo anywhere, as read only and using inode access times. Some matching mount commands: .Sp .Vb 1 \& $ mount \-o ro,atime /dev/foo /mnt \& \& $ mount \-o ro,atime /dev/foo /some/where/else .Ve .IP "\fBmount options in (ro,atime) /dev/foo,\fR" 4 .IX Item "mount options in (ro,atime) /dev/foo," allow mount of /dev/foo anywhere using some combination of 'ro' and 'atime' (see above). Some matching mount commands: .Sp .Vb 1 \& $ mount \-o ro /dev/foo /mnt \& \& $ mount \-o atime /dev/foo /some/where/else \& \& $ mount \-o ro,atime /dev/foo /some/other/place .Ve .IP "\fBmount options=ro /dev/foo, mount options=atime /dev/foo,\fR" 4 .IX Item "mount options=ro /dev/foo, mount options=atime /dev/foo," allow mount of /dev/foo anywhere as read only, and allow mount of /dev/foo anywhere using inode access times. Note this is expressed as two different rules. Matches: .Sp .Vb 1 \& $ mount \-o ro /dev/foo /mnt/1 \& \& $ mount \-o atime /dev/foo /mnt/2 .Ve .IP "\fBmount \-> /mnt/**,\fR" 4 .IX Item "mount -> /mnt/**," allow mounting anything under a directory in /mnt/**. Some matching mount commands: .Sp .Vb 1 \& $ mount /dev/foo1 /mnt/1 \& \& $ mount \-o ro,atime,noexec,nodiratime /dev/foo2 /mnt/deep/path/foo2 .Ve .IP "\fBmount options=ro \-> /mnt/**,\fR" 4 .IX Item "mount options=ro -> /mnt/**," allow mounting anything under /mnt/**, as read only. Some matching mount commands: .Sp .Vb 1 \& $ mount \-o ro /dev/foo1 /mnt/1 \& \& $ mount \-o ro /dev/foo2 /mnt/deep/path/foo2 .Ve .IP "\fBmount fstype=ext3 options=(rw,atime) /dev/sdb1 \-> /mnt/stick/,\fR" 4 .IX Item "mount fstype=ext3 options=(rw,atime) /dev/sdb1 -> /mnt/stick/," allow mounting an ext3 filesystem in /dev/sdb1 on /mnt/stick as read/write and using inode access times. Matches only: .Sp .Vb 1 \& $ mount \-o rw,atime /dev/sdb1 /mnt/stick .Ve .IP "\fBmount options=(ro, atime) options in (nodev, user) /dev/foo \-> /mnt/,\fR" 4 .IX Item "mount options=(ro, atime) options in (nodev, user) /dev/foo -> /mnt/," allow mounting /dev/foo on /mmt/ read only and using inode access times or allow mounting /dev/foo on /mnt/ with some combination of 'nodev' and 'user'. Matches only: .Sp .Vb 1 \& $ mount \-o ro,atime /dev/foo /mnt \& \& $ mount \-o nodev /dev/foo /mnt \& \& $ mount \-o user /dev/foo /mnt \& \& $ mount \-o nodev,user /dev/foo /mnt .Ve .SS "Pivot Root Rules" .IX Subsection "Pivot Root Rules" AppArmor mediates changing of the root filesystem through the \fIpivot_root\fR\|(2) system call. The syntax of 'pivot_root' rules in AppArmor is based on the \&\fIpivot_root\fR\|(2) system call parameters with the notable exception that the ordering is reversed. The path corresponding to the put_old parameter of \&\fIpivot_root\fR\|(2) is optionally specified in the 'pivot_root' rule using the \&'oldroot=' prefix. .PP AppArmor 'pivot_root' rules can specify a profile transition to occur during the \fIpivot_root\fR\|(2) system call. Note that AppArmor will only transition the process calling \fIpivot_root\fR\|(2) to the new profile. .PP The paths specified in 'pivot_root' rules must end with '/' since they are directories. .PP Here are some example 'pivot_root' rules: .PP .Vb 2 \& # Allow any pivot \& pivot_root, \& \& # Allow pivoting to any new root directory and putting the old root \& # directory at /mnt/root/old/ \& pivot_root oldroot=/mnt/root/old/, \& \& # Allow pivoting the root directory to /mnt/root/ \& pivot_root /mnt/root/, \& \& # Allow pivoting to /mnt/root/ and putting the old root directory at \& # /mnt/root/old/ \& pivot_root oldroot=/mnt/root/old/ /mnt/root/, \& \& # Allow pivoting to /mnt/root/, putting the old root directory at \& # /mnt/root/old/ and transition to the /mnt/root/sbin/init profile \& pivot_root oldroot=/mnt/root/old/ /mnt/root/ \-> /mnt/root/sbin/init, .Ve .SS "PTrace rules" .IX Subsection "PTrace rules" AppArmor supports mediation of \fIptrace\fR\|(2). AppArmor PTrace rules are accumulated so that the granted PTrace permissions are the union of all the listed PTrace rule permissions. .PP AppArmor PTrace permissions are implied when a rule does not explicitly state an access list. By default, all PTrace permissions are implied. .PP The trace and tracedby permissions govern \fIptrace\fR\|(2) while read and readby govern certain \fIproc\fR\|(5) filesystem accesses, \fIkcmp\fR\|(2), futexes (\fIget_robust_list\fR\|(2)) and perf trace events. .PP For a ptrace operation to be allowed the profile of the tracing process and the profile of the target task must both have the correct permissions. For example, the profile of the process attaching to another task must have the trace permission for the target task's profile, and the task being traced must have the tracedby permission for the tracing process' profile. .PP Example AppArmor PTrace rules: .PP .Vb 2 \& # Allow all PTrace access \& ptrace, \& \& # Explicitly allow all PTrace access, \& ptrace (read, readby, trace, tracedby), \& \& # Explicitly deny use of ptrace(2) \& deny ptrace (trace), \& \& # Allow unconfined processes (eg, a debugger) to ptrace us \& ptrace (readby, tracedby) peer=unconfined, \& \& # Allow ptrace of a process running under the /usr/bin/foo profile \& ptrace (trace) peer=/usr/bin/foo, .Ve .SS "Signal rules" .IX Subsection "Signal rules" AppArmor supports mediation of \fIsignal\fR\|(7). AppArmor signal rules are accumulated so that the granted signal permissions are the union of all the listed signal rule permissions. .PP AppArmor signal permissions are implied when a rule does not explicitly state an access list. By default, all signal permissions are implied. .PP For the sending of a signal to be allowed, the profile of the sending process and the profile of the target task must both have the correct permissions. For example, the profile of a process sending a signal to another task must have the send permission for the target task's profile, and the task receiving the signal must have a receive permission for the sending process' profile. .PP Example AppArmor signal rules: .PP .Vb 2 \& # Allow all signal access \& signal, \& \& # Explicitly deny sending the HUP and INT signals \& deny signal (send) set=(hup, int), \& \& # Allow unconfined processes to send us signals \& signal (receive) peer=unconfined, \& \& # Allow sending of signals to a process running under the /usr/bin/foo \& # profile \& signal (send) peer=/usr/bin/foo, \& \& # Allow checking for PID existence \& signal (receive, send) set=("exists"), \& \& # Allow us to signal ourselves using the built\-in @{profile_name} variable \& signal peer=@{profile_name}, \& \& # Allow two real\-time signals \& signal set=(rtmin+0 rtmin+32), .Ve .SS "DBus rules" .IX Subsection "DBus rules" AppArmor supports DBus mediation. The mediation is performed in conjunction with the DBus daemon. The DBus daemon verifies that communications over the bus are permitted by AppArmor policy. .PP AppArmor DBus rules are accumulated so that the granted DBus permissions are the union of all the listed DBus rule permissions. .PP AppArmor DBus rules are broad and general and become more restrictive as further information is specified. Policy may be specified down to the interface member level (method or signal name), however the contents of messages are not examined. .PP Some AppArmor DBus permissions are not compatible with all AppArmor DBus rules. The 'bind' permission cannot be used in message rules. The 'send' and 'receive' permissions cannot be used in service rules. The 'eavesdrop' permission cannot be used in rules containing any conditionals outside of the 'bus' conditional. .PP \&'r' and 'read' are synonyms for 'receive'. 'w' and 'write' are synonyms for \&'send'. 'rw' is a synonym for both 'send' and 'receive'. .PP AppArmor DBus permissions are implied when a rule does not explicitly state an access list. By default, all DBus permissions are implied. Only message permissions are implied for message rules and only service permissions are implied for service rules. .PP Example AppArmor DBus rules: .PP .Vb 2 \& # Allow all DBus access \& dbus, \& \& # Explicitly allow all DBus access, \& dbus (send, receive, bind), \& \& # Deny send/receive/bind access to the session bus \& deny dbus bus=session, \& \& # Allow bind access for a particular name on any bus \& dbus bind name=com.example.ExampleName, \& \& # Allow receive access for a particular path and interface \& dbus receive path=/com/example/path interface=com.example.Interface, \& \& # Deny send/receive access to the system bus for a particular interface \& deny dbus bus=system interface=com.example.ExampleInterface, \& \& # Allow send access for a particular path, interface, member, and pair of \& # peer names: \& dbus send \& bus=session \& path=/com/example/path \& interface=com.example.Interface \& member=ExampleMethod \& peer=(name=(com.example.ExampleName1|com.example.ExampleName2)), \& \& # Allow receive access for all unconfined peers \& dbus receive peer=(label=unconfined)), \& \& # Allow eavesdropping on the system bus \& dbus eavesdrop bus=system, \& \& # Allow and audit all eavesdropping \& audit dbus eavesdrop, .Ve .SS "Unix socket rules" .IX Subsection "Unix socket rules" AppArmor supports fine grained mediation of unix domain abstract and anonymous sockets. Unix domain sockets with file system paths are mediated via file access rules. .PP Abstract unix domain sockets is a nonportable Linux extension of unix domain sockets, see \fIunix\fR\|(7) for more information. .PP \fIUnix socket address paths\fR .IX Subsection "Unix socket address paths" .PP The sun_path component (aka the socket address) of a unix domain socket is specified by the .PP .Vb 1 \& addr= .Ve .PP conditional. If an address conditional is not specified as part of a rule then the rule matches both abstract and anonymous sockets. .PP In apparmor the address of an abstract unix domain socket begins with the \fI@\fR character, similar to how they are reported (as paths) by netstat \-x. The address then follows and may contain pattern matching and any characters including the null character. In apparmor null characters must be specified by using an escape sequence \fI\e000\fR or \&\fI\ex00\fR. The pattern matching is the same as is used by file path matching so * will not match \fI/\fR even though it has no special meaning with in an abstract socket name. Eg. .PP .Vb 1 \& unix addr=@*, .Ve .PP Anonymous unix domain sockets have no sun_path associated with the socket address, however it can be specified with the special \fInone\fR keyword to indicate the rule only applies to anonymous unix domain sockets. Eg. .PP .Vb 1 \& unix addr=none, .Ve .PP If the address component of a rule is not specified then the rule applies to both abstract and anonymous sockets. .PP \fIUnix socket permissions\fR .IX Subsection "Unix socket permissions" .PP Unix domain socket rules are accumulated so that the granted unix socket permissions are the union of all the listed unix rule permissions. .PP Unix domain socket rules are broad and general and become more restrictive as further information is specified. Policy may be specified down to the socket address (aka sun_path) and label level. The content of the communication is not examined. .PP Unix socket rule permissions are implied when a rule does not explicitly state an access list. By default if a rule does not have an access list all permissions that are compatible with the specified set of local and peer conditionals are implied. .PP The create, bind, listen, shutdown, getattr, setattr, getopt, and setopt permissions are local socket permissions. They are only applied to the local socket and can't be specified in rules that have a peer component. The accept permission applies to the combination of a local and peer socket. The connect, send, and receive permissions are peer socket permissions. .PP Only the peer socket permissions will be applied to rules that don't specify permissions and contain a peer component. .PP \fIExample Unix domain socket rules:\fR .IX Subsection "Example Unix domain socket rules:" .PP .Vb 2 \& # Allow all permissions to unix sockets \& unix, \& \& # Explicitly allow all unix permissions \& unix (create, listen, accept, connect, send, receive, getattr, setattr, setopt, getopt), \& \& # Explicitly deny unix socket access \& deny unix, \& \& # Allow create and use of abstract and anonymous sockets for profile_name \& unix peer=(label=@{profile_name}), \& \& # Allow receiving via unix sockets from unconfined \& unix (receive) peer=(label=unconfined), \& \& # Allow getattr and shutdown on anonymous sockets \& unix (getattr, shutdown) addr=none, \& \& # Allow SOCK_STREAM connect, receive and send on an abstract socket @bar \& # with peer running under profile \*(Aq/foo\*(Aq \& unix (connect, receive, send) type=stream peer=(label=/foo,addr="@bar"), \& \& # Allow accepting connections from and receiving from peer running under \& # profile \*(Aq/bar\*(Aq on abstract socket \*(Aq@foo\*(Aq \& unix (accept, receive) addr=@foo peer=(label=/bar), .Ve .PP \fIAbstract unix domain sockets autobind\fR .IX Subsection "Abstract unix domain sockets autobind" .PP Abstract unix domain sockets can autobind to an address. The autobind address is a unique 5 digit string of decimal numbers, eg. \f(CW@00001\fR. There is nothing that prevents a task from manually binding to addresses with a similar pattern so it is impossible to reliably identify autobind addresses from a regular address. .PP \fIInteraction of network rules and fine grained unix domain socket rules\fR .IX Subsection "Interaction of network rules and fine grained unix domain socket rules" .PP The coarse grained networking rules can be used to control unix domain sockets as well. When fine grained unix domain socket mediation is available the coarse grained network rule is mapped into the equivalent unix socket rule. .PP E.G. .PP .Vb 1 \& network unix, => unix, \& \& network unix stream, => unix stream, .Ve .PP Fine grained mediation rules however can not be lossly converted back to the coarse grained network rule; e.g. .PP .Vb 1 \& unix bind addr=@example, .Ve .PP Has no exact match under coarse grained network rules, the closest match is the much wider permission rule of .PP .Vb 1 \& network unix, .Ve .SS "change_profile rules" .IX Subsection "change_profile rules" AppArmor supports self directed profile transitions via the change_profile api. Change_profile rules control which permissions for which profiles a confined task can transition to. The profile name can contain apparmor pattern matching to specify different profiles. .PP .Vb 1 \& change_profile \-> **, .Ve .PP The change_profile api allows the transition to be delayed until when a task executes another application. If an exec rule transition is specified for the application and the change_profile api is used to make a transition at exec time, the transition specified by the change_profile api takes precedence. .PP The Change_profile permission can restrict which profiles can be transitioned to based off of the executable name by specifying the exec condition. .PP .Vb 1 \& change_profile /bin/bash \-> new_profile, .Ve .PP The restricting of the transition profile to a given executable at exec time is only useful when then current task is allowed to make dynamic decisions about what confinement should be, but the decision set needs to be controlled. A list of profiles or multiple rules can be used to specify the profiles in the set. Eg. .PP .Vb 1 \& change_profile /bin/bash \-> {new_profile1,new_profile2,new_profile3}, .Ve .PP An exec rule can be used to specify a transition for the executable, if the transition should be allowed even if the change_profile api has not been used to select a transition for those available in the change_profile rule set. Eg. .PP .Vb 2 \& /bin/bash Px \-> new_profile1, \& change_profile /bin/bash \-> {new_profile1,new_profile2,new_profile3}, .Ve .PP The exec mode dictates whether or not the Linux Kernel's \fBunsafe_exec\fR routines should be used to scrub the environment, similar to setuid programs. (See \fIld.so\fR\|(8) for some information on setuid/setgid environment scrubbing.) The \&\fBsafe\fR mode sets up environment scrubbing to occur when the new application is executed and \fBunsafe\fR mode disables AppArmor's requirement for environment scrubbing (the kernel and/or libc may still require environment scrubbing). An exec mode can only be specified when an exec condition is present. .PP .Vb 1 \& change_profile safe /bin/bash \-> new_profile, .Ve .PP Not all kernels support \fBsafe\fR mode and the parser will downgrade rules to \&\fBunsafe\fR mode in that situation. If no exec mode is specified, the default is \&\fBsafe\fR mode in kernels that support it. .SS "rlimit rules" .IX Subsection "rlimit rules" AppArmor can set and control the resource limits associated with a profile as described in the \fIsetrlimit\fR\|(2) man page. .PP The AppArmor rlimit controls allow setting of limits and restricting changes of them and these actions can be audited. Enforcement of the set limits is handled by the standard kernel enforcement mechanism for rlimits and will not result in an audited apparmor message if the limit is enforced. .PP If a profile does not have an rlimit rule associated with a given rlimit then the rlimit is left alone and regular access, including changing the limit, is allowed. However if the profile sets an rlimit then the current limit is checked and if greater than the limit specified in the rule it will be changed to the specified limit. .PP AppArmor rlimit rules control the hard limit of an application and ensure that if the hard limit is lowered that the soft limit does not exceed the hard limit value. .PP Eg. .PP .Vb 3 \& set rlimit data <= 100M, \& set rlimit nproc <= 10, \& set rlimit nice <= 5, .Ve .SS "Variables" .IX Subsection "Variables" AppArmor's policy language allows embedding variables into file rules to enable easier configuration for some common (and pervasive) setups. Variables may have multiple values assigned, but any variable assignments must be made before the start of the profile. .PP The parser will automatically expand variables to include all values that they have been assigned; it is an error to reference a variable without setting at least one value. You can use empty quotes ("") to explicitly add an empty value. .PP At the time of this writing, the following variables are defined in the provided AppArmor policy: .PP .Vb 10 \& @{HOME} \& @{HOMEDIRS} \& @{multiarch} \& @{pid} \& @{pids} \& @{PROC} \& @{securityfs} \& @{apparmorfs} \& @{sys} \& @{tid} \& @{XDG_DESKTOP_DIR} \& @{XDG_DOWNLOAD_DIR} \& @{XDG_TEMPLATES_DIR} \& @{XDG_PUBLICSHARE_DIR} \& @{XDG_DOCUMENTS_DIR} \& @{XDG_MUSIC_DIR} \& @{XDG_PICTURES_DIR} \& @{XDG_VIDEOS_DIR} .Ve .PP These are defined in files in \fI/etc/apparmor.d/tunables\fR and are used in many of the abstractions described later. .PP You may also add files in \fI/etc/apparmor.d/tunables/home.d\fR for site-specific customization of \fB@{\s-1HOMEDIRS\s0}\fR, \&\fI/etc/apparmor.d/tunables/multiarch.d\fR for \fB@{multiarch}\fR and \&\fI/etc/apparmor.d/tunables/xdg\-user\-dirs.d\fR for \fB@{XDG_*}\fR. .PP The special \fB@{profile_name}\fR variable is set to the profile name and may be used in all policy. .SS "Alias rules" .IX Subsection "Alias rules" AppArmor also provides alias rules for remapping paths for site-specific layouts. They are an alternative form of path rewriting to using variables, and are done after variable resolution. Alias rules must occur within the preamble of the profile. System-wide aliases are found in \&\fI/etc/apparmor.d/tunables/alias\fR, which is included by \&\fI/etc/apparmor.d/tunables/global\fR. \fI/etc/apparmor.d/tunables/global\fR is typically included at the beginning of an AppArmor profile. .SS "Globbing" .IX Subsection "Globbing" File resources may be specified with a globbing syntax similar to that used by popular shells, such as \fIcsh\fR\|(1), \fIbash\fR\|(1), \fIzsh\fR\|(1). .IP "\fB*\fR" 4 .IX Item "*" can substitute for any number of characters, excepting '/' .IP "\fB**\fR" 4 .IX Item "**" can substitute for any number of characters, including '/' .IP "\fB?\fR" 4 .IX Item "?" can substitute for any single character excepting '/' .IP "\fB[abc]\fR" 4 .IX Item "[abc]" will substitute for the single character a, b, or c .IP "\fB[a\-c]\fR" 4 .IX Item "[a-c]" will substitute for the single character a, b, or c .IP "\fB[^a\-c]\fR" 4 .IX Item "[^a-c]" will substitute for any single character not matching a, b or c .IP "\fB{ab,cd}\fR" 4 .IX Item "{ab,cd}" will expand to one rule to match ab, one rule to match cd .PP When AppArmor looks up a directory the pathname being looked up will end with a slash (e.g., \fI/var/tmp/\fR); otherwise it will not end with a slash. Only rules that match a trailing slash will match directories. Some examples, none matching the \fI/tmp/\fR directory itself, are: .IP "\fB/tmp/*\fR" 4 .IX Item "/tmp/*" Files directly in \fI/tmp\fR. .IP "\fB/tmp/*/\fR" 4 .IX Item "/tmp/*/" Directories directly in \fI/tmp\fR. .IP "\fB/tmp/**\fR" 4 .IX Item "/tmp/**" Files and directories anywhere underneath \fI/tmp\fR. .IP "\fB/tmp/**/\fR" 4 .IX Item "/tmp/**/" Directories anywhere underneath \fI/tmp\fR. .SS "Rule Qualifiers" .IX Subsection "Rule Qualifiers" There are several rule qualifiers that can be applied to permission rules. Rule qualifiers can modify the rule and/or permissions within the rule. .IP "\fBallow\fR" 4 .IX Item "allow" Specifies that permissions requests that match the rule are allowed. This is the default value for rules and does not need to be specified. Conflicts with the \fIdeny\fR qualifier. .IP "\fBaudit\fR" 4 .IX Item "audit" Specifies that permissions requests that match the rule should be recorded to the audit log. .IP "\fBdeny\fR" 4 .IX Item "deny" Specifies that permissions requests that match the rule should be denied without logging. Can be combined with 'audit' to enable logging. Conflicts with the \fIallow\fR qualifier. .IP "\fBowner\fR" 4 .IX Item "owner" Specifies that the task must have the same euid/fsuid as the object being referenced by the permission check. .PP \fIQualifier Blocks\fR .IX Subsection "Qualifier Blocks" .PP Rule Qualifiers can be applied to multiple rules at a time by grouping the rules into a rule block. .PP .Vb 4 \& audit { \& /foo r, \& network, \& } .Ve .SS "#include mechanism" .IX Subsection "#include mechanism" AppArmor provides an easy abstraction mechanism to group common access requirements; this abstraction is an extremely flexible way to grant site-specific rights and makes writing new AppArmor profiles very simple by assembling the needed building blocks for any given program. .PP The use of '#include' is modelled directly after \fIcpp\fR\|(1); its use will replace the '#include' statement with the specified file's contents. The leading '#' is optional, and the '#include' keyword can be followed by an option conditional 'if exists' that specifies profile compilation should continue if the specified file or directory is not found. .PP \&\fB#include \*(L"/absolute/path\*(R"\fR specifies that \fI/absolute/path\fR should be used. \fB#include \*(L"relative/path\*(R"\fR specifies that \fIrelative/path\fR should be used, where the path is relative to the current working directory. \&\fB#include \fR is the most common usage; it will load \&\fImagic/path\fR relative to a directory specified to \fIapparmor_parser\fR\|(8). \&\fI/etc/apparmor.d/\fR is the AppArmor default. .PP The supplied AppArmor profiles follow several conventions; the abstractions stored in \fI/etc/apparmor.d/abstractions/\fR are some large clusters that are used in most profiles. What follows are short descriptions of how some of the abstractions are used. .IP "\fIabstractions/audio\fR" 4 .IX Item "abstractions/audio" Includes accesses to device files used for audio applications. .IP "\fIabstractions/authentication\fR" 4 .IX Item "abstractions/authentication" Includes access to files and services typically necessary for services that perform user authentication. .IP "\fIabstractions/base\fR" 4 .IX Item "abstractions/base" Includes files that should be readable and writable in all profiles. .IP "\fIabstractions/bash\fR" 4 .IX Item "abstractions/bash" Includes many files used by bash; useful for interactive shells and programs that call \fIsystem\fR\|(3). .IP "\fIabstractions/consoles\fR" 4 .IX Item "abstractions/consoles" Includes read and write access to the device files controlling the virtual console, \fIsshd\fR\|(8), \fIxterm\fR\|(1), etc. This abstraction is needed for many programs that interact with users. .IP "\fIabstractions/fonts\fR" 4 .IX Item "abstractions/fonts" Includes access to fonts and the font libraries. .IP "\fIabstractions/gnome\fR" 4 .IX Item "abstractions/gnome" Includes read and write access to \s-1GNOME\s0 configuration files, as well as read access to \s-1GNOME\s0 libraries. .IP "\fIabstractions/kde\fR" 4 .IX Item "abstractions/kde" Includes read and write access to \s-1KDE\s0 configuration files, as well as read access to \s-1KDE\s0 libraries. .IP "\fIabstractions/kerberosclient\fR" 4 .IX Item "abstractions/kerberosclient" Includes file access rules needed for common kerberos clients. .IP "\fIabstractions/nameservice\fR" 4 .IX Item "abstractions/nameservice" Includes file rules to allow \s-1DNS, LDAP, NIS, SMB,\s0 user and group password databases, services, and protocols lookups. .IP "\fIabstractions/perl\fR" 4 .IX Item "abstractions/perl" Includes read access to perl modules. .IP "\fIabstractions/user\-download\fR" 4 .IX Item "abstractions/user-download" .PD 0 .IP "\fIabstractions/user\-mail\fR" 4 .IX Item "abstractions/user-mail" .IP "\fIabstractions/user\-manpages\fR" 4 .IX Item "abstractions/user-manpages" .IP "\fIabstractions/user\-tmp\fR" 4 .IX Item "abstractions/user-tmp" .IP "\fIabstractions/user\-write\fR" 4 .IX Item "abstractions/user-write" .PD Some profiles for typical \*(L"user\*(R" programs will use these include files to describe rights that users have in the system. .IP "\fIabstractions/wutmp\fR" 4 .IX Item "abstractions/wutmp" Includes write access to files used to maintain \fIwtmp\fR\|(5) and \fIutmp\fR\|(5) databases, used with the w(1) and associated commands. .IP "\fIabstractions/X\fR" 4 .IX Item "abstractions/X" Includes read access to libraries, configuration files, X authentication files, and the X socket. .PP Some of the abstractions rely on variables that are set in files in the \&\fI/etc/apparmor.d/tunables/\fR directory. These variables are currently \&\fB@{\s-1HOME\s0}\fR and \fB@{\s-1HOMEDIRS\s0}\fR. Variables cannot be set in profile scope; they can only be set before the profile. Therefore, any profiles that use abstractions should either \fB#include \fR or otherwise ensure that \fB@{\s-1HOME\s0}\fR and \fB@{\s-1HOMEDIRS\s0}\fR are set before starting the profile definition. The \fIaa\-autodep\fR\|(8) and \fIaa\-genprof\fR\|(8) utilities will automatically emit \fB#include \fR in generated profiles. .SH "EXAMPLE" .IX Header "EXAMPLE" An example AppArmor profile: .PP .Vb 2 \& # a variable definition in the preamble \& @{HOME} = /home/*/ /root/ \& \& # a comment about foo. \& /usr/bin/foo { \& /bin/mount ux, \& /dev/{,u}random r, \& /etc/ld.so.cache r, \& /etc/foo.conf r, \& /etc/foo/* r, \& /lib/ld\-*.so* rmix, \& /lib/lib*.so* r, \& /proc/[0\-9]** r, \& /usr/lib/** r, \& /tmp/foo.pid wr, \& /tmp/foo.* lrw, \& /@{HOME}/.foo_file rw, \& /usr/bin/baz Cx \-> baz, \& \& # a comment about foo\*(Aqs hat (subprofile), bar. \& ^bar { \& /lib/ld\-*.so* rmix, \& /usr/bin/bar rmix, \& /var/spool/* rwl, \& } \& \& # a comment about foo\*(Aqs subprofile, baz. \& profile baz { \& #include \& owner /proc/[0\-9]*/stat r, \& /bin/bash ixr, \& /var/lib/baz/ r, \& owner /var/lib/baz/* rw, \& } \& } .Ve .SH "FILES" .IX Header "FILES" .IP "\fI/etc/init.d/boot.apparmor\fR" 4 .IX Item "/etc/init.d/boot.apparmor" .PD 0 .IP "\fI/etc/apparmor.d/\fR" 4 .IX Item "/etc/apparmor.d/" .PD .SH "KNOWN BUGS" .IX Header "KNOWN BUGS" .IP "\(bu" 4 Mount options support the use of pattern matching but mount flags are not correctly intersected against specified patterns. Eg, 'mount options=**,' should be equivalent to 'mount,', but it is not. (\s-1LP:\s0 #965690) .IP "\(bu" 4 The fstype may not be matched against when certain mount command flags are used. Specifically fstype matching currently only works when creating a new mount and not remount, bind, etc. .IP "\(bu" 4 Mount rules with multiple 'options' conditionals are not applied as documented but instead merged such that 'options in (ro,nodev) options in (atime)' is equivalent to 'options in (ro,nodev,atime)'. .IP "\(bu" 4 When specifying mount options with the 'in' conditional, both the positive and negative values match when specifying one or the other. Eg, 'rw' matches when \&'ro' is specified and 'dev' matches when 'nodev' is specified such that \&'options in (ro,nodev)' is equivalent to 'options in (rw,dev)'. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7), \fIapparmor_parser\fR\|(8), \fIaa\-complain\fR\|(1), \&\fIaa\-enforce\fR\|(1), \fIaa_change_hat\fR\|(2), \fImod_apparmor\fR\|(5), and . apparmor-2.13.3/parser/ptrace.h0000644000175000017500000000276713502024172014144 0ustar jjjj/* * Copyright (c) 2014 * Canonical Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical * Ltd. */ #ifndef __AA_PTRACE_H #define __AA_PTRACE_H #include "immunix.h" #include "parser.h" #define AA_MAY_TRACE AA_MAY_WRITE #define AA_MAY_READBY 0x10 /* MAY_CREATE in new encoding */ #define AA_MAY_TRACEDBY AA_MAY_APPEND #define AA_VALID_PTRACE_PERMS (AA_MAY_READ | AA_MAY_TRACE | AA_MAY_READBY | \ AA_MAY_TRACEDBY) int parse_ptrace_mode(const char *str_mode, int *mode, int fail); class ptrace_rule: public rule_t { void move_conditionals(struct cond_entry *conds); public: char *peer_label; int mode; int audit; int deny; ptrace_rule(int mode, struct cond_entry *conds); virtual ~ptrace_rule() { free(peer_label); }; virtual ostream &dump(ostream &os); virtual int expand_variables(void); virtual int gen_policy_re(Profile &prof); virtual void post_process(Profile &prof unused) { }; }; #endif /* __AA_PTRACE_H */ apparmor-2.13.3/parser/network.h0000644000175000017500000000747213502024172014355 0ustar jjjj/* * Copyright (c) 2014 * Canonical, Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical * Ltd. */ #ifndef __AA_NETWORK_H #define __AA_NETWORK_H #include #include #include #include #include #include #include #include #include #include #include "parser.h" #include "rule.h" #define AA_NET_WRITE 0x0002 #define AA_NET_SEND AA_NET_WRITE #define AA_NET_READ 0x0004 #define AA_NET_RECEIVE AA_NET_READ #define AA_NET_CREATE 0x0010 #define AA_NET_SHUTDOWN 0x0020 /* alias delete */ #define AA_NET_CONNECT 0x0040 /* alias open */ #define AA_NET_SETATTR 0x0100 #define AA_NET_GETATTR 0x0200 //#define AA_NET_CHMOD 0x1000 /* pair */ //#define AA_NET_CHOWN 0x2000 /* pair */ //#define AA_NET_CHGRP 0x4000 /* pair */ //#define AA_NET_LOCK 0x8000 /* LINK_SUBSET overlaid */ #define AA_NET_ACCEPT 0x00100000 #define AA_NET_BIND 0x00200000 #define AA_NET_LISTEN 0x00400000 #define AA_NET_SETOPT 0x01000000 #define AA_NET_GETOPT 0x02000000 #define AA_CONT_MATCH 0x08000000 #define AA_VALID_NET_PERMS (AA_NET_SEND | AA_NET_RECEIVE | AA_NET_CREATE | \ AA_NET_SHUTDOWN | AA_NET_CONNECT | \ AA_NET_SETATTR | AA_NET_GETATTR | AA_NET_BIND | \ AA_NET_ACCEPT | AA_NET_LISTEN | AA_NET_SETOPT | \ AA_NET_GETOPT | AA_CONT_MATCH) #define AA_LOCAL_NET_PERMS (AA_NET_CREATE | AA_NET_SHUTDOWN | AA_NET_SETATTR |\ AA_NET_GETATTR | AA_NET_BIND | AA_NET_ACCEPT | \ AA_NET_LISTEN | AA_NET_SETOPT | AA_NET_GETOPT) #define AA_NET_OPT (AA_NET_SETOPT | AA_NET_GETOPT) #define AA_LOCAL_NET_CMD (AA_NET_LISTEN | AA_NET_OPT) #define AA_PEER_NET_PERMS (AA_VALID_NET_PERMS & (~AA_LOCAL_NET_PERMS | \ AA_NET_ACCEPT)) struct network_tuple { const char *family_name; unsigned int family; const char *type_name; unsigned int type; const char *protocol_name; unsigned int protocol; }; /* supported AF protocols */ struct aa_network_entry { unsigned int family; unsigned int type; unsigned int protocol; struct aa_network_entry *next; }; int parse_net_mode(const char *str_mode, int *mode, int fail); extern struct aa_network_entry *new_network_ent(unsigned int family, unsigned int type, unsigned int protocol); extern struct aa_network_entry *network_entry(const char *family, const char *type, const char *protocol); extern size_t get_af_max(void); void __debug_network(unsigned int *array, const char *name); struct network { unsigned int *allow; /* array of type masks * indexed by AF_FAMILY */ unsigned int *audit; unsigned int *deny; unsigned int *quiet; network(void) { allow = audit = deny = quiet = NULL; } void dump(void) { if (allow) __debug_network(allow, "Network"); if (audit) __debug_network(audit, "Audit Net"); if (deny) __debug_network(deny, "Deny Net"); if (quiet) __debug_network(quiet, "Quiet Net"); } }; int net_find_type_val(const char *type); const char *net_find_type_name(int type); const char *net_find_af_name(unsigned int af); const struct network_tuple *net_find_mapping(const struct network_tuple *map, const char *family, const char *type, const char *protocol); #endif /* __AA_NETWORK_H */ apparmor-2.13.3/parser/frob_slack_rc0000755000175000017500000000605113502024172015222 0ustar jjjj#!/usr/bin/perl -w # ---------------------------------------------------------------------- # Copyright (c) 2004, 2005 NOVELL (All rights reserved) # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Novell, Inc. # ---------------------------------------------------------------------- use Getopt::Long; use File::Temp qw/ :mktemp /; use File::stat; sub usage { print "$0\t(--init|--shutdown) \tmodify startup or shutdown script\n"; print "\t\t\t--file= \tmodify \n"; print "\t\t\t--remove \tremove option from config file\n"; print "\t\t\t--help \t\tthis help\n"; print '$Revision: 1.1 $', "\n"; exit(0); } my ($conffile,$help,$remove,$init,$shutdown); GetOptions( "file=s" => \$conffile, "init" => \$init, "shutdown" => \$shutdown, "remove" => \$remove, "help!" => \$help ) or usage(); usage() if ($help); my ($my_regexp, $my_command); if (defined $init) { $my_regexp = '^echo "Going multiuser..."$'; $my_command = "start"; } elsif (defined $shutdown) { $my_regexp = '^# Kill all processes.$'; $my_command = "kill"; } else { usage(); } if (defined $conffile) { $old = $conffile; chomp($old); } elsif (defined $init) { $old="/etc/rc.d/rc.M"; } elsif (defined $shutdown) { $old="/etc/rc.d/rc.K"; } open(MENU,"<$old") or die "Fatal: can't open $old: $!"; ($fh, $file) = mkstemp($old . "XXXXXX" ); my $skip = FALSE; while () { # ok, we rely on the '="' to site the changes ; if (! defined $remove) { if ( /$my_regexp/ ) { print $fh $_; print $fh "# BEGIN rc.apparmor INSERTION\n"; print $fh "if [ -x /etc/rc.d/rc.apparmor ] ; then\n"; print $fh " /etc/rc.d/rc.apparmor $my_command\n"; print $fh "fi\n"; print $fh "# END rc.apparmor INSERTION\n"; } elsif ( /^# BEGIN rc.subdomain INSERTION$/ ) { $skip = TRUE; } elsif ( $skip eq TRUE ) { if ( /^# END rc.subdomain INSERTION$/ ) { $skip = FALSE; } } else { print $fh $_; } } elsif ( /^# BEGIN rc.(apparmor\|subdomain) INSERTION$/ ) { $skip = TRUE; } elsif ( $skip eq TRUE ) { if ( /^# END rc.(apparmor\|subdomain) INSERTION$/ ) { $skip = FALSE; } } else { print $fh $_; } } my $sb = stat($old) || die "Could not get permission bits from $old"; my $oldmode = $sb->mode & 07777; rename $old, "$old.orig" || system("/bin/mv", $old, "$old.orig") && die "$old could not be renamed to $old.orig ($!); see $file for modifications"; rename $file, "$old" || system("/bin/mv", $file, "$old") && die "$file could not be renamed to $old ($!); see $file for modifications"; chmod $oldmode, $old || die "COuld not restore permission bits on $old"; apparmor-2.13.3/parser/parser_main.c0000644000175000017500000010754113502024172015155 0ustar jjjj/* * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 * NOVELL (All rights reserved) * * Copyright (c) 2010 - 2018 * Canonical Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical, * Ltd. */ #include #include #include #include #include #include #include #include #include /* enable the following line to get voluminous debug info */ /* #define DEBUG */ #include #include #include #include #include #include #include "lib.h" #include "features.h" #include "parser.h" #include "parser_version.h" #include "parser_include.h" #include "common_optarg.h" #include "policy_cache.h" #include "libapparmor_re/apparmor_re.h" #define OLD_MODULE_NAME "subdomain" #define PROC_MODULES "/proc/modules" #define MATCH_FILE "/sys/kernel/security/" MODULE_NAME "/matching" #define MOUNTED_FS "/proc/mounts" #define AADFA "pattern=aadfa" #define PRIVILEGED_OPS (kernel_load) #define UNPRIVILEGED_OPS (!(PRIVILEGED_OPS)) #define EARLY_ARG_CONFIG_FILE 141 const char *parser_title = "AppArmor parser"; const char *parser_copyright = "Copyright (C) 1999-2008 Novell Inc.\nCopyright 2009-2018 Canonical Ltd."; int opt_force_complain = 0; int binary_input = 0; int dump_vars = 0; int dump_expanded_vars = 0; int show_cache = 0; int skip_cache = 0; int skip_read_cache = 0; int write_cache = 0; int cond_clear_cache = 1; /* only applies if write is set */ int force_clear_cache = 0; /* force clearing regargless of state */ int create_cache_dir = 0; /* DEPRECATED in favor of write_cache */ int preprocess_only = 0; int skip_mode_force = 0; int abort_on_error = 0; /* stop processing profiles if error */ int skip_bad_cache_rebuild = 0; int mru_skip_cache = 1; int debug_cache = 0; /* for jobs_max and jobs * LONG_MAX : no limit * 0 : auto = detect system processing cores * n : use that number of processes/threads to compile policy */ #define JOBS_AUTO 0 long jobs_max = -8; /* 8 * cpus */ long jobs = JOBS_AUTO; /* default: number of processor cores */ long njobs = 0; long jobs_scale = 0; /* number of chance to resample online * cpus. This allows jobs spawning to * scale when scheduling policy is * taking cpus off line, and brings * them back with load */ bool debug_jobs = false; #define MAX_CACHE_LOCS 4 struct timespec cache_tstamp, mru_policy_tstamp; static char *apparmorfs = NULL; static const char *cacheloc[MAX_CACHE_LOCS]; static int cacheloc_n = 0; static bool print_cache_dir = false; static aa_features *compile_features = NULL; static aa_features *kernel_features = NULL; static const char *config_file = "/etc/apparmor/parser.conf"; /* Make sure to update BOTH the short and long_options */ static const char *short_options = "ad::f:h::rRVvI:b:BCD:NSm:M:qQn:XKTWkL:O:po:j:"; struct option long_options[] = { {"add", 0, 0, 'a'}, {"binary", 0, 0, 'B'}, {"base", 1, 0, 'b'}, {"subdomainfs", 1, 0, 'f'}, {"help", 2, 0, 'h'}, {"replace", 0, 0, 'r'}, {"reload", 0, 0, 'r'}, /* undocumented reload option == replace */ {"version", 0, 0, 'V'}, {"complain", 0, 0, 'C'}, {"Complain", 0, 0, 'C'}, /* Erk, apparently documented as --Complain */ {"Include", 1, 0, 'I'}, {"remove", 0, 0, 'R'}, {"names", 0, 0, 'N'}, {"stdout", 0, 0, 'S'}, {"ofile", 1, 0, 'o'}, {"match-string", 1, 0, 'm'}, {"features-file", 1, 0, 'M'}, {"quiet", 0, 0, 'q'}, {"skip-kernel-load", 0, 0, 'Q'}, {"verbose", 0, 0, 'v'}, {"namespace", 1, 0, 'n'}, {"readimpliesX", 0, 0, 'X'}, {"skip-cache", 0, 0, 'K'}, {"skip-read-cache", 0, 0, 'T'}, {"write-cache", 0, 0, 'W'}, {"show-cache", 0, 0, 'k'}, {"cache-loc", 1, 0, 'L'}, {"debug", 2, 0, 'd'}, {"dump", 1, 0, 'D'}, {"Dump", 1, 0, 'D'}, {"optimize", 1, 0, 'O'}, {"Optimize", 1, 0, 'O'}, {"preprocess", 0, 0, 'p'}, {"jobs", 1, 0, 'j'}, {"skip-bad-cache", 0, 0, 129}, /* no short option */ {"purge-cache", 0, 0, 130}, /* no short option */ {"create-cache-dir", 0, 0, 131}, /* no short option */ {"abort-on-error", 0, 0, 132}, /* no short option */ {"skip-bad-cache-rebuild", 0, 0, 133}, /* no short option */ {"warn", 1, 0, 134}, /* no short option */ {"debug-cache", 0, 0, 135}, /* no short option */ {"max-jobs", 1, 0, 136}, /* no short option */ {"print-cache-dir", 0, 0, 137}, /* no short option */ {"kernel-features", 1, 0, 138}, /* no short option */ {"compile-features", 1, 0, 139}, /* no short option */ {"print-config-file", 0, 0, 140}, /* no short option */ {"config-file", 1, 0, EARLY_ARG_CONFIG_FILE}, /* early option, no short option */ {NULL, 0, 0, 0}, }; static int debug = 0; void display_version(void) { printf("%s version " PARSER_VERSION "\n%s\n", parser_title, parser_copyright); } static void display_usage(const char *command) { display_version(); printf("\nUsage: %s [options] [profile]\n\n" "Options:\n" "--------\n" "-a, --add Add apparmor definitions [default]\n" "-r, --replace Replace apparmor definitions\n" "-R, --remove Remove apparmor definitions\n" "-C, --Complain Force the profile into complain mode\n" "-B, --binary Input is precompiled profile\n" "-N, --names Dump names of profiles in input.\n" "-S, --stdout Dump compiled profile to stdout\n" "-o n, --ofile n Write output to file n\n" "-b n, --base n Set base dir and cwd\n" "-I n, --Include n Add n to the search path\n" "-f n, --subdomainfs n Set location of apparmor filesystem\n" "-m n, --match-string n Use only features n\n" "-M n, --features-file n Set compile & kernel features to file n\n" "--compile-features n Compile features set in file n\n" "--kernel-features n Kernel features set in file n\n" "-n n, --namespace n Set Namespace for the profile\n" "-X, --readimpliesX Map profile read permissions to mr\n" "-k, --show-cache Report cache hit/miss details\n" "-K, --skip-cache Do not attempt to load or save cached profiles\n" "-T, --skip-read-cache Do not attempt to load cached profiles\n" "-W, --write-cache Save cached profile (force with -T)\n" " --skip-bad-cache Don't clear cache if out of sync\n" " --purge-cache Clear cache regardless of its state\n" " --debug-cache Debug cache file checks\n" " --print-cache_dir Print the cache directory path\n" "-L, --cache-loc n Set the location of the profile caches\n" "-q, --quiet Don't emit warnings\n" "-v, --verbose Show profile names as they load\n" "-Q, --skip-kernel-load Do everything except loading into kernel\n" "-V, --version Display version info and exit\n" "-d [n], --debug Debug apparmor definitions OR [n]\n" "-p, --preprocess Dump preprocessed profile\n" "-D [n], --dump Dump internal info for debugging\n" "-O [n], --Optimize Control dfa optimizations\n" "-h [cmd], --help[=cmd] Display this text or info about cmd\n" "-j n, --jobs n Set the number of compile threads\n" "--max-jobs n Hard cap on --jobs. Default 8*cpus\n" "--abort-on-error Abort processing of profiles on first error\n" "--skip-bad-cache-rebuild Do not try rebuilding the cache if it is rejected by the kernel\n" "--config-file n Specify the parser config file location, processed early before other options.\n" "--print-config Print config file location\n" "--warn n Enable warnings (see --help=warn)\n" ,command); } optflag_table_t warnflag_table[] = { { 0, "rule-not-enforced", "warn if a rule is not enforced", WARN_RULE_NOT_ENFORCED }, { 0, "rule-downgraded", "warn if a rule is downgraded to a lesser but still enforcing rule", WARN_RULE_DOWNGRADED }, { 0, NULL, NULL, 0 }, }; void display_warn(const char *command) { display_version(); printf("\n%s: --warn [Option]\n\n" "Options:\n" "--------\n" ,command); print_flag_table(warnflag_table); } /* Parse comma separated cachelocations. Commas can be escaped by \, */ static int parse_cacheloc(const char *arg, const char **cacheloc, int max_size) { const char *s = arg; const char *p = arg; int n = 0; while(*p) { if (*p == '\\') { if (*(p + 1) != 0) p++; } else if (*p == ',') { if (p != s) { char *tmp; if (n == max_size) { errno = E2BIG; return -1; } tmp = (char *) malloc(p - s + 1); if (tmp == NULL) return -1; memcpy(tmp, s, p - s); tmp[p - s] = 0; cacheloc[n] = tmp; n++; } p++; s = p; } else p++; } if (p != s) { char *tmp; if (n == max_size) { errno = E2BIG; return -1; } tmp = (char *) malloc(p - s + 1); if (tmp == NULL) return -1; memcpy(tmp, s, p - s); tmp[p - s] = 0; cacheloc[n] = tmp; n++; } return n; } /* Treat conf file like options passed on command line */ static int getopt_long_file(FILE *f, const struct option *longopts, char **optarg, int *longindex) { static char line[256]; char *pos, *opt, *save; int i; for (;;) { if (!fgets(line, 256, f)) return -1; pos = line; while (isblank(*pos)) pos++; if (*pos == '#') continue; opt = strtok_r(pos, " \t\r\n=", &save); /* blank line */ if (!opt) continue; for (i = 0; longopts[i].name && strcmp(longopts[i].name, opt) != 0; i++) ; if (!longopts[i].name) { PERROR("%s: unknown option (%s) in config file.\n", progname, opt); /* skip it */ continue; } break; } if (longindex) *longindex = i; if (*save) { int len; while(isblank(*save)) save++; len = strlen(save) - 1; if (save[len] == '\n') save[len] = 0; } switch (longopts[i].has_arg) { case 0: *optarg = NULL; break; case 1: if (!strlen(save)) { *optarg = NULL; return '?'; } *optarg = save; break; case 2: *optarg = save; break; default: PERROR("%s: internal error bad longopt value\n", progname); exit(1); } if (longopts[i].flag == NULL) return longopts[i].val; else *longopts[i].flag = longopts[i].val; return 0; } static long process_jobs_arg(const char *arg, const char *val) { char *end; long n; if (!val || strcmp(val, "auto") == 0) n = JOBS_AUTO; else if (strcmp(val, "max") == 0) n = LONG_MAX; else { bool multiple = false; if (*val == 'x') { multiple = true; val++; } n = strtol(val, &end, 0); if (!(*val && val != end && *end == '\0')) { PERROR("%s: Invalid option %s=%s%s\n", progname, arg, multiple ? "x" : "", val); exit(1); } if (multiple) n = -n; } return n; } bool early_arg(int c) { switch(c) { case EARLY_ARG_CONFIG_FILE: return true; } return false; } /* process a single argment from getopt_long * Returns: 1 if an action arg, else 0 */ static int process_arg(int c, char *optarg) { int count = 0; switch (c) { case 0: PERROR("Assert, in getopt_long handling\n"); exit(1); break; case 'a': count++; option = OPTION_ADD; break; case 'd': if (!optarg) { debug++; skip_read_cache = 1; } else if (strcmp(optarg, "jobs") == 0 || strcmp(optarg, "j") == 0) { debug_jobs = true; } else { PERROR("%s: Invalid --debug option '%s'\n", progname, optarg); exit(1); } break; case 'h': if (!optarg) { display_usage(progname); } else if (strcmp(optarg, "Dump") == 0 || strcmp(optarg, "dump") == 0 || strcmp(optarg, "D") == 0) { display_dump(progname); } else if (strcmp(optarg, "Optimize") == 0 || strcmp(optarg, "optimize") == 0 || strcmp(optarg, "O") == 0) { display_optimize(progname); } else if (strcmp(optarg, "warn") == 0) { display_warn(progname); } else { PERROR("%s: Invalid --help option %s\n", progname, optarg); exit(1); } exit(0); break; case 'r': count++; option = OPTION_REPLACE; break; case 'R': count++; option = OPTION_REMOVE; skip_cache = 1; break; case 'V': display_version(); exit(0); break; case 'I': add_search_dir(optarg); break; case 'b': set_base_dir(optarg); break; case 'B': binary_input = 1; skip_cache = 1; break; case 'C': opt_force_complain = 1; skip_cache = 1; break; case 'N': count++; names_only = 1; skip_cache = 1; kernel_load = 0; break; case 'S': count++; option = OPTION_STDOUT; skip_read_cache = 1; kernel_load = 0; break; case 'o': count++; option = OPTION_OFILE; skip_read_cache = 1; kernel_load = 0; ofile = fopen(optarg, "w"); if (!ofile) { PERROR("%s: Could not open file %s\n", progname, optarg); exit(1); } break; case 'f': apparmorfs = strndup(optarg, PATH_MAX); break; case 'D': skip_read_cache = 1; if (!optarg) { dump_vars = 1; } else if (strcmp(optarg, "variables") == 0) { dump_vars = 1; } else if (strcmp(optarg, "expanded-variables") == 0) { dump_expanded_vars = 1; } else if (!handle_flag_table(dumpflag_table, optarg, &dfaflags)) { PERROR("%s: Invalid --Dump option %s\n", progname, optarg); exit(1); } break; case 'O': if (!handle_flag_table(optflag_table, optarg, &dfaflags)) { PERROR("%s: Invalid --Optimize option %s\n", progname, optarg); exit(1); } break; case 'm': if (aa_features_new_from_string(&compile_features, optarg, strlen(optarg))) { fprintf(stderr, "Failed to parse features string: %m\n"); exit(1); } break; case 'M': if (compile_features) aa_features_unref(compile_features); if (kernel_features) aa_features_unref(kernel_features); if (aa_features_new(&compile_features, AT_FDCWD, optarg)) { fprintf(stderr, "Failed to load features from '%s': %m\n", optarg); exit(1); } kernel_features = aa_features_ref(compile_features); break; case 138: if (kernel_features) aa_features_unref(kernel_features); if (aa_features_new(&kernel_features, AT_FDCWD, optarg)) { fprintf(stderr, "Failed to load kernel features from '%s': %m\n", optarg); exit(1); } break; case 139: if (compile_features) aa_features_unref(compile_features); if (aa_features_new(&compile_features, AT_FDCWD, optarg)) { fprintf(stderr, "Failed to load compile features from '%s': %m\n", optarg); exit(1); } break; case 'q': conf_verbose = 0; conf_quiet = 1; warnflags = 0; break; case 'v': conf_verbose = 1; conf_quiet = 0; break; case 'n': profile_ns = strdup(optarg); break; case 'X': read_implies_exec = 1; break; case 'K': skip_cache = 1; break; case 'k': show_cache = 1; break; case 'W': write_cache = 1; break; case 'T': skip_read_cache = 1; break; case 129: cond_clear_cache = 0; break; case 130: force_clear_cache = 1; break; case 131: create_cache_dir = 1; break; case 132: abort_on_error = 1; break; case 133: skip_bad_cache_rebuild = 1; break; case 'L': cacheloc_n = parse_cacheloc(optarg, cacheloc, MAX_CACHE_LOCS); if (cacheloc_n == -1) { PERROR("%s: Invalid --cacheloc option '%s' %m\n", progname, optarg); exit(1); } break; case 'Q': kernel_load = 0; break; case 'p': count++; kernel_load = 0; skip_cache = 1; preprocess_only = 1; skip_mode_force = 1; break; case 134: if (!handle_flag_table(warnflag_table, optarg, &warnflags)) { PERROR("%s: Invalid --warn option %s\n", progname, optarg); exit(1); } break; case 135: debug_cache = 1; break; case 'j': jobs = process_jobs_arg("-j", optarg); break; case 136: jobs_max = process_jobs_arg("max-jobs", optarg); break; case 137: kernel_load = 0; print_cache_dir = true; break; case EARLY_ARG_CONFIG_FILE: config_file = strdup(optarg); if (!config_file) { PERROR("%s: %m", progname); exit(1); } break; case 140: printf("%s\n", config_file); break; default: /* 'unrecognized option' error message gets printed by getopt_long() */ exit(1); break; } return count; } static void process_early_args(int argc, char *argv[]) { int c, o; while ((c = getopt_long(argc, argv, short_options, long_options, &o)) != -1) { if (early_arg(c)) process_arg(c, optarg); } /* reset args, so we are ready for a second pass */ optind = 1; } static int process_args(int argc, char *argv[]) { int c, o; int count = 0; option = OPTION_ADD; opterr = 1; while ((c = getopt_long(argc, argv, short_options, long_options, &o)) != -1) { if (!early_arg(c)) count += process_arg(c, optarg); } if (count > 1) { PERROR("%s: Too many actions given on the command line.\n", progname); exit(1); } PDEBUG("optind = %d argc = %d\n", optind, argc); return optind; } static int process_config_file(const char *name) { char *optarg; autofclose FILE *f = NULL; int c, o; f = fopen(name, "r"); if (!f) { pwarn("config file '%s' not found\n", name); return 0; } while ((c = getopt_long_file(f, long_options, &optarg, &o)) != -1) process_arg(c, optarg); return 1; } int have_enough_privilege(void) { uid_t uid, euid; uid = getuid(); euid = geteuid(); if (uid != 0 && euid != 0) { PERROR(_("%s: Sorry. You need root privileges to run this program.\n\n"), progname); return EPERM; } if (uid != 0 && euid == 0) { PERROR(_("%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update " "your AppArmor profiles.\n\n"), progname); } return 0; } static void set_features_by_match_file(void) { autofclose FILE *ms = fopen(MATCH_FILE, "r"); if (ms) { autofree char *match_string = (char *) malloc(1000); if (!match_string) goto no_match; if (!fgets(match_string, 1000, ms)) goto no_match; if (strstr(match_string, " perms=c")) perms_create = 1; kernel_supports_network = 1; return; } no_match: perms_create = 1; } static void set_supported_features(aa_features *kernel_features unused) { /* has process_args() already assigned a match string? */ if (!compile_features && aa_features_new_from_kernel(&compile_features) == -1) { set_features_by_match_file(); return; } /* * TODO: intersect with actual kernel features to get proper * rule down grades for a give kernel */ perms_create = 1; kernel_supports_policydb = aa_features_supports(compile_features, "file"); kernel_supports_network = aa_features_supports(compile_features, "network"); kernel_supports_unix = aa_features_supports(compile_features, "network/af_unix"); kernel_supports_mount = aa_features_supports(compile_features, "mount"); kernel_supports_dbus = aa_features_supports(compile_features, "dbus"); kernel_supports_signal = aa_features_supports(compile_features, "signal"); kernel_supports_ptrace = aa_features_supports(compile_features, "ptrace"); kernel_supports_setload = aa_features_supports(compile_features, "policy/set_load"); kernel_supports_diff_encode = aa_features_supports(compile_features, "policy/diff_encode"); kernel_supports_stacking = aa_features_supports(compile_features, "domain/stack"); if (aa_features_supports(compile_features, "policy/versions/v7")) kernel_abi_version = 7; else if (aa_features_supports(compile_features, "policy/versions/v6")) kernel_abi_version = 6; if (!kernel_supports_diff_encode) /* clear diff_encode because it is not supported */ dfaflags &= ~DFA_CONTROL_DIFF_ENCODE; } static bool do_print_cache_dir(aa_features *features, int dirfd, const char *path) { autofree char *cache_dir = NULL; cache_dir = aa_policy_cache_dir_path_preview(features, dirfd, path); if (!cache_dir) { PERROR(_("Unable to print the cache directory: %m\n")); return false; } printf("%s\n", cache_dir); return true; } static bool do_print_cache_dirs(aa_features *features, const char **cacheloc, int cacheloc_n) { int i; for (i = 0; i < cacheloc_n; i++) { if (!do_print_cache_dir(features, AT_FDCWD, cacheloc[i])) return false; } return true; } int process_binary(int option, aa_kernel_interface *kernel_interface, const char *profilename) { const char *printed_name; int retval; printed_name = profilename ? profilename : "stdin"; if (kernel_load) { if (option == OPTION_ADD) { retval = profilename ? aa_kernel_interface_load_policy_from_file(kernel_interface, AT_FDCWD, profilename) : aa_kernel_interface_load_policy_from_fd(kernel_interface, 0); if (retval == -1) { retval = errno; PERROR(_("Error: Could not load profile %s: %s\n"), printed_name, strerror(retval)); return retval; } } else if (option == OPTION_REPLACE) { retval = profilename ? aa_kernel_interface_replace_policy_from_file(kernel_interface, AT_FDCWD, profilename) : aa_kernel_interface_replace_policy_from_fd(kernel_interface, 0); if (retval == -1) { retval = errno; PERROR(_("Error: Could not replace profile %s: %s\n"), printed_name, strerror(retval)); return retval; } } else { PERROR(_("Error: Invalid load option specified: %d\n"), option); return EINVAL; } } if (conf_verbose) { switch (option) { case OPTION_ADD: printf(_("Cached load succeeded for \"%s\".\n"), printed_name); break; case OPTION_REPLACE: printf(_("Cached reload succeeded for \"%s\".\n"), printed_name); break; default: break; } } return 0; } void reset_parser(const char *filename) { memset(&mru_policy_tstamp, 0, sizeof(mru_policy_tstamp)); memset(&cache_tstamp, 0, sizeof(cache_tstamp)); mru_skip_cache = 1; free_aliases(); free_symtabs(); free_policies(); reset_include_stack(filename); } int test_for_dir_mode(const char *basename, const char *linkdir) { int rc = 0; if (!skip_mode_force) { autofree char *target = NULL; if (asprintf(&target, "%s/%s/%s", basedir, linkdir, basename) < 0) { perror("asprintf"); exit(1); } if (access(target, R_OK) == 0) rc = 1; } return rc; } int process_profile(int option, aa_kernel_interface *kernel_interface, const char *profilename, aa_policy_cache *pc) { int retval = 0; autofree const char *cachename = NULL; autofree const char *writecachename = NULL; autofree const char *cachetmpname = NULL; autoclose int cachetmp = -1; const char *basename = NULL; /* per-profile states */ force_complain = opt_force_complain; if (profilename) { if ( !(yyin = fopen(profilename, "r")) ) { PERROR(_("Error: Could not read profile %s: %s.\n"), profilename, strerror(errno)); return errno; } } else { if (write_cache) pwarn("%s: cannot use or update cache, disable, or force-complain via stdin\n", progname); skip_cache = write_cache = 0; } reset_parser(profilename); if (profilename && option != OPTION_REMOVE) { /* make decisions about disabled or complain-mode profiles */ basename = strrchr(profilename, '/'); if (basename) basename++; else basename = profilename; if (test_for_dir_mode(basename, "disable")) { if (!conf_quiet) PERROR("Skipping profile in %s/disable: %s\n", basedir, basename); goto out; } if (test_for_dir_mode(basename, "force-complain")) { PERROR("Warning: found %s in %s/force-complain, forcing complain mode\n", basename, basedir); force_complain = 1; } /* setup cachename and tstamp */ if (!force_complain && pc) { cachename = aa_policy_cache_filename(pc, basename); if (!cachename) { autoclose int fd = aa_policy_cache_open(pc, basename, O_RDONLY); if (fd != -1) pwarn(_("Could not get cachename for '%s'\n"), basename); } else { valid_read_cache(cachename); } } } if (yyin) { yyrestart(yyin); update_mru_tstamp(yyin, profilename ? profilename : "stdin"); } retval = yyparse(); if (retval != 0) goto out; /* Test to see if profile is for another namespace, if so disable * caching for now * TODO: Add support for caching profiles in an alternate namespace * TODO: Add support for embedded namespace defines if they aren't * removed from the language. * TODO: test profile->ns NOT profile_ns (must be after parse) */ if (profile_ns) skip_cache = 1; if (cachename) { /* Load a binary cache if it exists and is newest */ if (cache_hit(cachename)) { retval = process_binary(option, kernel_interface, cachename); if (!retval || skip_bad_cache_rebuild) return retval; } } if (show_cache) PERROR("Cache miss: %s\n", profilename ? profilename : "stdin"); if (preprocess_only) goto out; if (names_only) { dump_policy_names(); goto out; } if (dump_vars) { dump_symtab(); goto out; } retval = post_process_policy(debug); if (retval != 0) { PERROR(_("%s: Errors found in file. Aborting.\n"), progname); goto out; } if (dump_expanded_vars) { dump_expanded_symtab(); goto out; } if (debug > 0) { printf("----- Debugging built structures -----\n"); dump_policy(); goto out; } if (pc && write_cache && !force_complain) { writecachename = cache_filename(pc, 0, basename); if (!writecachename) { pwarn("Cache write disabled: Cannot create cache file name '%s': %m\n", basename); write_cache = 0; } cachetmp = setup_cache_tmp(&cachetmpname, writecachename); if (cachetmp == -1) { pwarn("Cache write disabled: Cannot create setup tmp cache file '%s': %m\n", writecachename); write_cache = 0; } } /* cache file generated by load_policy */ retval = load_policy(option, kernel_interface, cachetmp); if (retval == 0 && write_cache) { if (cachetmp == -1) { unlink(cachetmpname); pwarn("Warning failed to create cache: %s\n", basename); } else { install_cache(cachetmpname, writecachename); } } out: return retval; } /* Do not call directly, this is a helper for work_sync, which can handle * single worker cases and cases were the work queue is optimized away * * call only if there are work children to wait on */ #define work_sync_one(RESULT) \ do { \ int status; \ wait(&status); \ if (WIFEXITED(status)) \ RESULT(WEXITSTATUS(status)); \ else \ RESULT(ECHILD); \ /* TODO: do we need to handle traced */ \ njobs--; \ if (debug_jobs) \ fprintf(stderr, " JOBS SYNC ONE: result %d, jobs left %ld\n", status, njobs); \ } while (0) #define work_sync(RESULT) \ do { \ if (debug_jobs) \ fprintf(stderr, "JOBS SYNC: jobs left %ld\n", njobs); \ while (njobs) \ work_sync_one(RESULT); \ } while (0) /* returns -1 if work_spawn fails, not a return value of any unit of work */ #define work_spawn(WORK, RESULT) \ ({ \ int localrc = 0; \ do { \ /* what to do to avoid fork() overhead when single threaded \ if (jobs == 1) { \ // no parallel work so avoid fork() overhead \ RESULT(WORK); \ break; \ }*/ \ if (jobs_scale) { \ long n = sysconf(_SC_NPROCESSORS_ONLN); \ if (n > jobs_max) \ n = jobs_max; \ if (n > jobs) { \ /* reset sample chances - potentially reduce to 0 */ \ jobs_scale = jobs_max - n; \ jobs = n; \ } else \ /* reduce scaling chance by 1 */ \ jobs_scale--; \ } \ if (njobs == jobs) { \ /* wait for a child */ \ if (debug_jobs) \ fprintf(stderr, " JOBS SPAWN: waiting (jobs %ld == max %ld) ...\n", njobs, jobs); \ work_sync_one(RESULT); \ } \ \ pid_t child = fork(); \ if (child == 0) { \ /* child - exit work unit with returned value */ \ exit(WORK); \ } else if (child > 0) { \ /* parent */ \ njobs++; \ if (debug_jobs) \ fprintf(stderr, " JOBS SPAWN: created %ld ...\n", njobs); \ } else { \ /* error */ \ if (debug_jobs) { \ int error = errno; \ fprintf(stderr, " JOBS SPAWN: failed error: %d) ...\n", errno); \ errno = error; \ } \ RESULT(errno); \ localrc = -1; \ } \ } while (0); \ localrc; \ }) /* sadly C forces us to do this with exit, long_jump or returning error * from work_spawn and work_sync. We could throw a C++ exception, is it * worth doing it to avoid the exit here. * * atm not all resources maybe cleanedup at exit */ int last_error = 0; void handle_work_result(int retval) { if (retval) { last_error = retval; if (abort_on_error) { /* already in abort mode we don't need subsequent * syncs to do this too */ abort_on_error = 0; work_sync(handle_work_result); exit(last_error); } } } static long compute_jobs(long n, long j) { if (j == JOBS_AUTO) j = n; else if (j < 0) j = n * j * -1; return j; } static void setup_parallel_compile(void) { /* jobs and paralell_max set by default, config or args */ long n = sysconf(_SC_NPROCESSORS_ONLN); long maxn = sysconf(_SC_NPROCESSORS_CONF); if (n == -1) /* unable to determine number of processors, default to 1 */ n = 1; if (maxn == -1) /* unable to determine number of processors, default to 1 */ maxn = 1; jobs = compute_jobs(n, jobs); jobs_max = compute_jobs(maxn, jobs_max); if (jobs > jobs_max) { pwarn("%s: Warning capping number of jobs to %ld * # of cpus == '%ld'", progname, jobs_max, jobs); jobs = jobs_max; } else if (jobs < jobs_max) /* the bigger the difference the more sample chances given */ jobs_scale = jobs_max + 1 - n; njobs = 0; if (debug_jobs) fprintf(stderr, "jobs: %ld\n", jobs); } struct dir_cb_data { aa_kernel_interface *kernel_interface; const char *dirname; /* name of the parent dir */ aa_policy_cache *policy_cache; /* policy_cache to use */ }; /* data - pointer to a dir_cb_data */ static int profile_dir_cb(int dirfd unused, const char *name, struct stat *st, void *data) { int rc = 0; if (!S_ISDIR(st->st_mode) && !is_blacklisted(name, NULL)) { struct dir_cb_data *cb_data = (struct dir_cb_data *)data; autofree char *path = NULL; if (asprintf(&path, "%s/%s", cb_data->dirname, name) < 0) { PERROR(_("Out of memory")); handle_work_result(errno); return -1; } rc = work_spawn(process_profile(option, cb_data->kernel_interface, path, cb_data->policy_cache), handle_work_result); } return rc; } /* data - pointer to a dir_cb_data */ static int binary_dir_cb(int dirfd unused, const char *name, struct stat *st, void *data) { int rc = 0; if (!S_ISDIR(st->st_mode) && !is_blacklisted(name, NULL)) { struct dir_cb_data *cb_data = (struct dir_cb_data *)data; autofree char *path = NULL; if (asprintf(&path, "%s/%s", cb_data->dirname, name) < 0) { PERROR(_("Out of memory")); handle_work_result(errno); return -1; } rc = work_spawn(process_binary(option, cb_data->kernel_interface, path), handle_work_result); } return rc; } static void setup_flags(void) { /* Gracefully handle AppArmor kernel without compatibility patch */ if (!kernel_features && aa_features_new_from_kernel(&kernel_features) == -1) { PERROR("Cache read/write disabled: interface file missing. " "(Kernel needs AppArmor 2.4 compatibility patch.)\n"); write_cache = 0; skip_read_cache = 1; return; } /* Get the match string to determine type of regex support needed */ set_supported_features(kernel_features); } int main(int argc, char *argv[]) { aa_kernel_interface *kernel_interface = NULL; aa_policy_cache *policy_cache = NULL; int retval; int i; int optind; /* name of executable, for error reporting and usage display */ progname = argv[0]; init_base_dir(); process_early_args(argc, argv); process_config_file(config_file); optind = process_args(argc, argv); setup_parallel_compile(); setlocale(LC_MESSAGES, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); /* Check to see if we have superuser rights, if we're not * debugging */ if (!(UNPRIVILEGED_OPS) && ((retval = have_enough_privilege()))) { return retval; } if (!binary_input) parse_default_paths(); setup_flags(); if (!(UNPRIVILEGED_OPS) && aa_kernel_interface_new(&kernel_interface, kernel_features, apparmorfs) == -1) { PERROR(_("Warning: unable to find a suitable fs in %s, is it " "mounted?\nUse --subdomainfs to override.\n"), MOUNTED_FS); return 1; } if ((!skip_cache && (write_cache || !skip_read_cache)) || print_cache_dir || force_clear_cache) { uint16_t max_caches = write_cache && cond_clear_cache ? (uint16_t) (-1) : 0; if (!cacheloc[0]) { cacheloc[0] = "/var/cache/apparmor"; cacheloc_n = 1; } if (print_cache_dir) return do_print_cache_dirs(kernel_features, cacheloc, cacheloc_n) ? 0 : 1; if (force_clear_cache) { /* only ever write to the first cacheloc location */ if (aa_policy_cache_remove(AT_FDCWD, cacheloc[0])) { PERROR(_("Failed to clear cache files (%s): %s\n"), cacheloc[0], strerror(errno)); return 1; } return 0; } if (create_cache_dir) pwarn(_("The --create-cache-dir option is deprecated. Please use --write-cache.\n")); retval = aa_policy_cache_new(&policy_cache, kernel_features, AT_FDCWD, cacheloc[0], max_caches); if (retval) { if (errno != ENOENT && errno != EEXIST && errno != EROFS) { PERROR(_("Failed setting up policy cache (%s): %s\n"), cacheloc[0], strerror(errno)); return 1; } if (show_cache) { if (max_caches > 0) PERROR("Cache write disabled: Cannot create cache '%s': %m\n", cacheloc[0]); else PERROR("Cache read/write disabled: Policy cache is invalid: %m\n"); } write_cache = 0; } else { if (show_cache) PERROR("Cache: added primary location '%s'\n", cacheloc[0]); for (i = 1; i < cacheloc_n; i++) { if (aa_policy_cache_add_ro_dir(policy_cache, AT_FDCWD, cacheloc[i])) { pwarn("Cache: failed to add read only location '%s', does not contain valid cache directory for the specified feature set\n", cacheloc[i]); } else if (show_cache) pwarn("Cache: added readonly location '%s'\n", cacheloc[i]); } } } retval = last_error = 0; for (i = optind; i <= argc; i++) { struct stat stat_file; if (i < argc && !(profilename = strdup(argv[i]))) { perror("strdup"); last_error = ENOMEM; if (abort_on_error) break; continue; } /* skip stdin if we've seen other command line arguments */ if (i == argc && optind != argc) goto cleanup; if (profilename && stat(profilename, &stat_file) == -1) { last_error = errno; PERROR("File %s not found, skipping...\n", profilename); if (abort_on_error) break; goto cleanup; } if (profilename && S_ISDIR(stat_file.st_mode)) { int (*cb)(int dirfd, const char *name, struct stat *st, void *data); struct dir_cb_data cb_data; memset(&cb_data, 0, sizeof(struct dir_cb_data)); cb_data.dirname = profilename; cb_data.policy_cache = policy_cache; cb_data.kernel_interface = kernel_interface; cb = binary_input ? binary_dir_cb : profile_dir_cb; if ((retval = dirat_for_each(AT_FDCWD, profilename, &cb_data, cb))) { last_error = errno; PDEBUG("Failed loading profiles from %s\n", profilename); if (abort_on_error) break; } } else if (binary_input) { /* ignore return as error is handled in work_spawn */ work_spawn(process_binary(option, kernel_interface, profilename), handle_work_result); } else { /* ignore return as error is handled in work_spawn */ work_spawn(process_profile(option, kernel_interface, profilename, policy_cache), handle_work_result); } cleanup: if (profilename) free(profilename); profilename = NULL; } work_sync(handle_work_result); if (ofile) fclose(ofile); aa_policy_cache_unref(policy_cache); return last_error; } apparmor-2.13.3/parser/README.devel0000644000175000017500000000727013502024172014465 0ustar jjjjAppArmor parser development notes and tips ========================================== Debugging the build ------------------- Adding V=1 as argument to make should result in build commands that are normally quieter generating more verbose output. This can help diagnose when something is going wrong at build time. Distribution vendors may wish to enable this option all the time to assist debugging build failures in remote build environments. Generally, they should not need to enable any other build flags/options. Building the parser with debugging information ---------------------------------------------- Setting DEBUG=1 with make will enable debugging output in the parser (i.e. PDEBUG statements will be emitted instead of dropped). Usually, partial compilation between debug and non-debug will cause compilation problems, so it's usually best to do something like make clean all DEBUG=1 Test Coverage ------------- The parser can be built to generate test coverage information, by setting the COVERAGE variable for make. As with debugging, partial compilation is usually problematic, so it's recommended to do: make clean all COVERAGE=1 and then run whatever tests. Because the unit tests are built with the make check target, in order to see what coverage they provide, they will also need to be built with the COVERAGE flag set: make tests COVERAGE=1 or, if running the unit tests with all the other parser tests: make check COVERAGE=1 Coverage information will be written out in files in the source build tree (*.gcno and *.gcda files). The 'gcovr' utility is useful for reading and summarizing the results; to do so, after running your tests, do something like: gcovr -r /PATH/TO/YOUR/PARSER/BUILD/TREE Of course, having test coverage over a given line of code won't indicate that the code is bug free; however, not having coverage indicates that the tests do not exercise the given code at all. That said, 100% coverage is unlikely to be possible in a testing environment, given checks for things like error handling for failed memory allocations. Finding memory leaks -------------------- The tst/ subdirectory has a python script for running valgrind on the parser over the test files in the simple_tests/ tree. This can take over 24 hours to complete, so it is not part of the default tests; however, it can be run manually or via the 'valgrind' make target. Valgrind reports some false positives for some additional checks it makes; the script attempts to suppress those (read the valgrind documentation for more details on suppressions). It can also emit the suppressions via the --dump-suppressions argument, to be used for manual valgrind runs. An example manual valgrind run could be something like: ./tst/valgrind_simply.py --dump-suppressions > /tmp/valgrind.suppression valgrind --leak-check=full --suppressions=/tmp/valgrind.suppression ./apparmor_parser -QK /path/to/profile Profiling (for performance) the parser -------------------------------------- # Using valgrind's callgrind tool Valgrind provides the callgrind tool to give some indication where hot spots are in the parser. To do so, do: valgrind --tool=callgrind ./apparmor_parser PARSER_ARGS This will generate a data file that a tool like kcachegrind can read. # Using gprof This can be enabled by adding the -pg argument as a CFLAG [1] at build time and then exercising the parser. A data file will be generated that gprof(1) can then read to show where the parser is spending the most time. [1] Unfortunately, only the DEBUG option in the Makefile does this, which enables other debugging options that alters the parser in ways that make it a less accurate representation of real world performance. This needs to be fixed. apparmor-2.13.3/parser/subdomain.conf.5.html0000644000175000017500000000667513502024374016461 0ustar jjjj
 

NAME

/etc/apparmor/subdomain.conf - configuration file for fine-tuning the behavior of the AppArmor security tool.

DESCRIPTION

The AppArmor security tool can be configured to have certain default behaviors based on configuration options set in subdomain.conf. There are two variables that can be set in subdomain.conf: SUBDOMAIN_PATH, and SUBDOMAIN_MODULE_PANIC.

SUBDOMAIN_PATH

This variable accepts a string (path), and is by default set to '/etc/apparmor.d/' This variable defines where the AppArmor security tool looks for its policy definitions (a.k.a. AppArmor profiles).

SUBDOMAIN_MODULE_PANIC

This variable accepts a string that is one of four values: warn, build, panic, or build-panic, and is set by default to warn.

This setting controls the behavior of the AppArmor initscript if it cannot successfully load the AppArmor kernel module on startup. The four possible settings are:

warn

Log a failure message (the default behavior).

build

Attempt to build the AppArmor module against the currently running kernel. If the compilation is successful, the module will be loaded and AppArmor started; if the compilation fails, a failure message is logged.

panic

Log a failure message and drop to runlevel 1 (single user).

build-panic

Attempt to build the module against the running kernel (like build) and if the compilation fails, drop to runlevel 1 (single user).

BUGS

Setting the initscript to recompile the module will fail on SUSE, as the module source is no longer installed by default. However, the module has been included with the SUSE kernel, so no rebuilding should be necessary.

If you find any additional bugs, please report them at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7), apparmor_parser(8), and https://wiki.apparmor.net.

 
apparmor-2.13.3/parser/rc.apparmor.redhat0000644000175000017500000000504613502024172016123 0ustar jjjj#!/bin/sh # ---------------------------------------------------------------------- # Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 # NOVELL (All rights reserved) # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Novell, Inc. # ---------------------------------------------------------------------- # rc.apparmor by Steve Beattie # # /etc/init.d/apparmor # # chkconfig: 2345 01 99 # description: AppArmor rc file. This rc script inserts the apparmor \ # module and runs the parser on the /etc/apparmor.d/ \ # directory. # ### BEGIN INIT INFO # Provides: apparmor # Required-Start: # Required-Stop: # Default-Start: 3 4 5 # Default-Stop: 0 1 2 6 # Short-Description: AppArmor initialization # Description: AppArmor rc file. This rc script inserts the apparmor # module and runs the parser on the /etc/apparmor.d/ # directory. ### END INIT INFO APPARMOR_FUNCTIONS=/lib/apparmor/rc.apparmor.functions # source function library if [ -f /etc/init.d/functions ]; then . /etc/init.d/functions elif [ -f /etc/rc.d/init.d/functions ]; then . /etc/rc.d/init.d/functions elif [ -f /lib/lsb/init-functions ]; then . /lib/lsb/init-functions else exit 0 fi usage() { echo "Usage: $0 {start|stop|restart|try-restart|reload|force-reload|status|kill}" } aa_log_success_msg() { echo -n "$*" success echo } aa_log_warning_msg() { echo -n "$*" warning echo } aa_log_skipped_msg() { echo -n "$*" warning echo } aa_log_failure_msg() { echo -n "$*" failure echo } aa_action() { STRING=$1 shift action "${STRING} " "$@" return $? } # source apparmor function library if [ -f "${APPARMOR_FUNCTIONS}" ]; then . ${APPARMOR_FUNCTIONS} else aa_log_failure_msg "Unable to find AppArmor initscript functions" exit 1 fi case "$1" in start) apparmor_start rc=$? ;; stop) apparmor_stop rc=$? ;; restart|reload|force-reload) apparmor_restart rc=$? ;; try-restart) apparmor_try_restart rc=$? ;; kill) apparmor_kill rc=$? ;; status) apparmor_status rc=$? ;; *) usage exit 1 ;; esac exit $rc apparmor-2.13.3/parser/dbus.cc0000644000175000017500000002032213502024172013744 0ustar jjjj/* * Copyright (c) 2013 * Canonical, Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical * Ltd. */ #include #include #include #include #include #include #include #include "parser.h" #include "profile.h" #include "parser_yacc.h" #include "dbus.h" int parse_dbus_mode(const char *str_mode, int *mode, int fail) { return parse_X_mode("DBus", AA_VALID_DBUS_PERMS, str_mode, mode, fail); } void dbus_rule::move_conditionals(struct cond_entry *conds) { struct cond_entry *cond_ent; list_for_each(conds, cond_ent) { /* for now disallow keyword 'in' (list) */ if (!cond_ent->eq) yyerror("keyword \"in\" is not allowed in dbus rules\n"); if (list_len(cond_ent->vals) > 1) yyerror("dbus conditional \"%s\" only supports a single value\n", cond_ent->name); if (strcmp(cond_ent->name, "bus") == 0) { move_conditional_value("dbus", &bus, cond_ent); } else if (strcmp(cond_ent->name, "name") == 0) { move_conditional_value("dbus", &name, cond_ent); } else if (strcmp(cond_ent->name, "label") == 0) { move_conditional_value("dbus", &peer_label, cond_ent); } else if (strcmp(cond_ent->name, "path") == 0) { move_conditional_value("dbus", &path, cond_ent); } else if (strcmp(cond_ent->name, "interface") == 0) { move_conditional_value("dbus", &interface, cond_ent); } else if (strcmp(cond_ent->name, "member") == 0) { move_conditional_value("dbus", &member, cond_ent); } else { yyerror("invalid dbus conditional \"%s\"\n", cond_ent->name); } } } dbus_rule::dbus_rule(int mode_p, struct cond_entry *conds, struct cond_entry *peer_conds): bus(NULL), name(NULL), peer_label(NULL), path(NULL), interface(NULL), member(NULL), mode(0), audit(0), deny(0) { int name_is_subject_cond = 0, message_rule = 0, service_rule = 0; /* Move the global/subject conditionals over & check the results */ move_conditionals(conds); if (name) name_is_subject_cond = 1; if (peer_label) yyerror("dbus \"label\" conditional can only be used inside of the \"peer=()\" grouping\n"); /* Move the peer conditionals */ move_conditionals(peer_conds); if (path || interface || member || peer_label || (name && !name_is_subject_cond)) message_rule = 1; if (name && name_is_subject_cond) service_rule = 1; if (message_rule && service_rule) yyerror("dbus rule contains message conditionals and service conditionals\n"); /* Copy mode. If no mode was specified, assign an implied mode. */ if (mode_p) { mode = mode_p; if (mode & ~AA_VALID_DBUS_PERMS) yyerror("mode contains unknown dbus access\n"); else if (message_rule && (mode & AA_DBUS_BIND)) yyerror("dbus \"bind\" access cannot be used with message rule conditionals\n"); else if (service_rule && (mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE))) yyerror("dbus \"send\" and/or \"receive\" accesses cannot be used with service rule conditionals\n"); else if (mode & AA_DBUS_EAVESDROP && (path || interface || member || peer_label || name)) { yyerror("dbus \"eavesdrop\" access can only contain a bus conditional\n"); } } else { if (message_rule) mode = (AA_DBUS_SEND | AA_DBUS_RECEIVE); else if (service_rule) mode = (AA_DBUS_BIND); else mode = AA_VALID_DBUS_PERMS; } free_cond_list(conds); free_cond_list(peer_conds); } ostream &dbus_rule::dump(ostream &os) { if (audit) os << "audit "; if (deny) os << "deny "; os << "dbus ( "; if (mode & AA_DBUS_SEND) os << "send "; if (mode & AA_DBUS_RECEIVE) os << "receive "; if (mode & AA_DBUS_BIND) os << "bind "; if (mode & AA_DBUS_EAVESDROP) os << "eavesdrop "; os << ")"; if (bus) os << " bus=\"" << bus << "\""; if ((mode & AA_DBUS_BIND) && name) os << " name=\"" << name << "\""; if (path) os << " path=\"" << path << "\""; if (interface) os << " interface=\"" << interface << "\""; if (member) os << " member=\"" << member << "\""; if (!(mode & AA_DBUS_BIND) && (peer_label || name)) { os << " peer=( "; if (peer_label) os << "label=\"" << peer_label << "\" "; if (name) os << "name=\"" << name << "\" "; os << ")"; } os << ",\n"; return os; } int dbus_rule::expand_variables(void) { int error = expand_entry_variables(&bus); if (error) return error; error = expand_entry_variables(&name); if (error) return error; error = expand_entry_variables(&peer_label); if (error) return error; error = expand_entry_variables(&path); if (error) return error; error = expand_entry_variables(&interface); if (error) return error; error = expand_entry_variables(&member); if (error) return error; return 0; } /* do we want to warn once/profile or just once per compile?? */ static void warn_once(const char *name) { static const char *warned_name = NULL; if ((warnflags & WARN_RULE_NOT_ENFORCED) && warned_name != name) { cerr << "Warning from profile " << name << " ("; if (current_filename) cerr << current_filename; else cerr << "stdin"; cerr << ") dbus rules not enforced\n"; warned_name = name; } } int dbus_rule::gen_policy_re(Profile &prof) { std::string busbuf; std::string namebuf; std::string peer_labelbuf; std::string pathbuf; std::string ifacebuf; std::string memberbuf; std::ostringstream buffer; const char *vec[6]; pattern_t ptype; int pos; if (!kernel_supports_dbus) { warn_once(prof.name); return RULE_NOT_SUPPORTED; } buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_DBUS; busbuf.append(buffer.str()); if (bus) { ptype = convert_aaregex_to_pcre(bus, 0, glob_default, busbuf, &pos); if (ptype == ePatternInvalid) goto fail; } else { /* match any char except \000 0 or more times */ busbuf.append(default_match_pattern); } vec[0] = busbuf.c_str(); if (name) { ptype = convert_aaregex_to_pcre(name, 0, glob_default, namebuf, &pos); if (ptype == ePatternInvalid) goto fail; vec[1] = namebuf.c_str(); } else { /* match any char except \000 0 or more times */ vec[1] = default_match_pattern; } if (peer_label) { ptype = convert_aaregex_to_pcre(peer_label, 0, glob_default, peer_labelbuf, &pos); if (ptype == ePatternInvalid) goto fail; vec[2] = peer_labelbuf.c_str(); } else { /* match any char except \000 0 or more times */ vec[2] = default_match_pattern; } if (path) { ptype = convert_aaregex_to_pcre(path, 0, glob_default, pathbuf, &pos); if (ptype == ePatternInvalid) goto fail; vec[3] = pathbuf.c_str(); } else { /* match any char except \000 0 or more times */ vec[3] = default_match_pattern; } if (interface) { ptype = convert_aaregex_to_pcre(interface, 0, glob_default, ifacebuf, &pos); if (ptype == ePatternInvalid) goto fail; vec[4] = ifacebuf.c_str(); } else { /* match any char except \000 0 or more times */ vec[4] = default_match_pattern; } if (member) { ptype = convert_aaregex_to_pcre(member, 0, glob_default, memberbuf, &pos); if (ptype == ePatternInvalid) goto fail; vec[5] = memberbuf.c_str(); } else { /* match any char except \000 0 or more times */ vec[5] = default_match_pattern; } if (mode & AA_DBUS_BIND) { if (!prof.policy.rules->add_rule_vec(deny, mode & AA_DBUS_BIND, audit & AA_DBUS_BIND, 2, vec, dfaflags)) goto fail; } if (mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) { if (!prof.policy.rules->add_rule_vec(deny, mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE), audit & (AA_DBUS_SEND | AA_DBUS_RECEIVE), 6, vec, dfaflags)) goto fail; } if (mode & AA_DBUS_EAVESDROP) { if (!prof.policy.rules->add_rule_vec(deny, mode & AA_DBUS_EAVESDROP, audit & AA_DBUS_EAVESDROP, 1, vec, dfaflags)) goto fail; } return RULE_OK; fail: return RULE_ERROR; } apparmor-2.13.3/parser/network.c0000644000175000017500000002343613502024172014346 0ustar jjjj/* * Copyright (c) 2014 * Canonical, Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical * Ltd. */ #include #include #include #include #include #include #include #include "lib.h" #include "parser.h" #include "profile.h" #include "parser_yacc.h" #include "network.h" int parse_net_mode(const char *str_mode, int *mode, int fail) { return parse_X_mode("net", AA_VALID_NET_PERMS, str_mode, mode, fail); } /* Bleah C++ doesn't have non-trivial designated initializers so we just * have to make sure these are in order. This means we are more brittle * but there isn't much we can do. */ struct sock_type_map { const char *name; int value; }; struct sock_type_map sock_types[] = { { "none", 0 }, { "stream", SOCK_STREAM }, { "dgram", SOCK_DGRAM }, { "raw", SOCK_RAW }, { "rdm", SOCK_RDM }, { "seqpacket", SOCK_SEQPACKET }, { "dccp", SOCK_DCCP }, { "invalid", -1 }, { "invalid", -1 }, { "invalid", -1 }, { "packet", SOCK_PACKET }, { NULL, -1 }, /* * See comment above */ }; int net_find_type_val(const char *type) { int i; for (i = 0; sock_types[i].name; i++) { if (strcmp(sock_types[i].name, type) == 0) return sock_types[i].value; } return -1; } const char *net_find_type_name(int type) { int i; for (i = 0; sock_types[i].name; i++) { if (sock_types[i].value == type) return sock_types[i].name; } return NULL; } /* FIXME: currently just treating as a bit mask this will have to change * set up a table of mappings, there can be several mappings for a * given match. * currently the mapping does not set the protocol for stream/dgram to * anything other than 0. * network inet tcp -> network inet stream 0 instead of * network inet raw tcp. * some entries are just provided for completeness at this time */ /* values stolen from /etc/protocols - needs to change */ #define RAW_TCP 6 #define RAW_UDP 17 #define RAW_ICMP 1 #define RAW_ICMPv6 58 /* used by af_name.h to auto generate table entries for "name", AF_NAME * pair */ #define AA_GEN_NET_ENT(name, AF) \ {name, AF, "stream", SOCK_STREAM, "", 0xffffff}, \ {name, AF, "dgram", SOCK_DGRAM, "", 0xffffff}, \ {name, AF, "seqpacket", SOCK_SEQPACKET, "", 0xffffff}, \ {name, AF, "rdm", SOCK_RDM, "", 0xffffff}, \ {name, AF, "raw", SOCK_RAW, "", 0xffffff}, \ {name, AF, "packet", SOCK_PACKET, "", 0xffffff}, /*FIXME: missing {name, AF, "dccp", SOCK_DCCP, "", 0xfffffff}, */ static struct network_tuple network_mappings[] = { /* basic types */ #include "af_names.h" /* FIXME: af_names.h is missing AF_LLC, AF_TIPC */ /* mapped types */ {"inet", AF_INET, "raw", SOCK_RAW, "tcp", 1 << RAW_TCP}, {"inet", AF_INET, "raw", SOCK_RAW, "udp", 1 << RAW_UDP}, {"inet", AF_INET, "raw", SOCK_RAW, "icmp", 1 << RAW_ICMP}, {"inet", AF_INET, "tcp", SOCK_STREAM, "", 0xffffffff}, /* should we give raw tcp too? */ {"inet", AF_INET, "udp", SOCK_DGRAM, "", 0xffffffff}, /* should these be open masks? */ {"inet", AF_INET, "icmp", SOCK_RAW, "", 1 << RAW_ICMP}, {"inet6", AF_INET6, "tcp", SOCK_STREAM, "", 0xffffffff}, {"inet6", AF_INET6, "udp", SOCK_DGRAM, "", 0xffffffff}, /* what do we do with icmp on inet6? {"inet6", AF_INET, "icmp", SOCK_RAW, 0}, {"inet6", AF_INET, "icmpv6", SOCK_RAW, 0}, */ /* terminate */ {NULL, 0, NULL, 0, NULL, 0} }; /* The apparmor kernel patches up until 2.6.38 didn't handle networking * tables with sizes > AF_MAX correctly. This could happen when the * parser was built against newer kernel headers and then used to load * policy on an older kernel. This could happen during upgrades or * in multi-kernel boot systems. * * Try to detect the running kernel version and use that to determine * AF_MAX */ #define PROC_VERSION "/proc/sys/kernel/osrelease" static size_t kernel_af_max(void) { char buffer[32]; int major; autoclose int fd = -1; int res; if (!net_af_max_override) { return 0; } /* the override parameter is specifying the max value */ if (net_af_max_override > 0) return net_af_max_override; fd = open(PROC_VERSION, O_RDONLY); if (fd == -1) /* fall back to default provided during build */ return 0; res = read(fd, &buffer, sizeof(buffer) - 1); if (res <= 0) return 0; buffer[res] = '\0'; res = sscanf(buffer, "2.6.%d", &major); if (res != 1) return 0; switch(major) { case 24: case 25: case 26: return 34; case 27: return 35; case 28: case 29: case 30: return 36; case 31: case 32: case 33: case 34: case 35: return 37; case 36: case 37: return 38; /* kernels .38 and later should handle this correctly so no * static mapping needed */ default: return 0; } } /* Yuck. We grab AF_* values to define above from linux/socket.h because * they are more accurate than sys/socket.h for what the kernel actually * supports. However, we can't just include linux/socket.h directly, * because the AF_* definitions are protected with an ifdef KERNEL * wrapper, but we don't want to define that because that can cause * other redefinitions from glibc. However, because the kernel may have * more definitions than glibc, we need make sure AF_MAX reflects this, * hence the wrapping function. */ size_t get_af_max() { size_t af_max; /* HACK: declare that version without "create" had a static AF_MAX */ if (!perms_create && !net_af_max_override) net_af_max_override = -1; #if AA_AF_MAX > AF_MAX af_max = AA_AF_MAX; #else af_max = AF_MAX; #endif /* HACK: some kernels didn't handle network tables from parsers * compiled against newer kernel headers as they are larger than * the running kernel expected. If net_override is defined check * to see if there is a static max specified for that kernel */ if (net_af_max_override) { size_t max = kernel_af_max(); if (max && max < af_max) return max; } return af_max; } struct aa_network_entry *new_network_ent(unsigned int family, unsigned int type, unsigned int protocol) { struct aa_network_entry *new_entry; new_entry = (struct aa_network_entry *) calloc(1, sizeof(struct aa_network_entry)); if (new_entry) { new_entry->family = family; new_entry->type = type; new_entry->protocol = protocol; new_entry->next = NULL; } return new_entry; } const struct network_tuple *net_find_mapping(const struct network_tuple *map, const char *family, const char *type, const char *protocol) { if (!map) map = network_mappings; else /* assumes it points to last entry returned */ map++; for (; map->family_name; map++) { if (family) { PDEBUG("Checking family %s\n", map->family_name); if (strcmp(family, map->family_name) != 0) continue; PDEBUG("Found family %s\n", family); } if (type) { PDEBUG("Checking type %s\n", map->type_name); if (strcmp(type, map->type_name) != 0) continue; PDEBUG("Found type %s\n", type); } if (protocol) { /* allows the proto to be the "type", ie. tcp implies * stream */ if (!type) { PDEBUG("Checking protocol type %s\n", map->type_name); if (strcmp(protocol, map->type_name) == 0) goto match; } PDEBUG("Checking type %s protocol %s\n", map->type_name, map->protocol_name); if (strcmp(protocol, map->protocol_name) != 0) continue; /* fixme should we allow specifying protocol by # * without needing the protocol mapping? */ } /* if we get this far we have a match */ match: return map; } return NULL; } struct aa_network_entry *network_entry(const char *family, const char *type, const char *protocol) { struct aa_network_entry *new_entry, *entry = NULL; const struct network_tuple *mapping = NULL; while ((mapping = net_find_mapping(mapping, family, type, protocol))) { new_entry = new_network_ent(mapping->family, mapping->type, mapping->protocol); if (!new_entry) yyerror(_("Memory allocation error.")); new_entry->next = entry; entry = new_entry; } return entry; }; #define ALL_TYPES 0x43e const char *net_find_af_name(unsigned int af) { size_t i; if (af < 0 || af > get_af_max()) return NULL; for (i = 0; i < sizeof(network_mappings) / sizeof(*network_mappings); i++) { if (network_mappings[i].family == af) return network_mappings[i].family_name; } return NULL; } void __debug_network(unsigned int *array, const char *name) { unsigned int count = sizeof(sock_types)/sizeof(sock_types[0]); unsigned int mask = ~((1 << count) -1); unsigned int i, j; int none = 1; size_t af_max = get_af_max(); for (i = AF_UNSPEC; i < af_max; i++) if (array[i]) { none = 0; break; } if (none) return; printf("%s: ", name); /* This can only be set by an unqualified network rule */ if (array[AF_UNSPEC]) { printf("\n"); return; } for (i = 0; i < af_max; i++) { if (array[i]) { const char *fam = net_find_af_name(i); if (fam) printf("%s ", fam); else printf("#%u ", i); /* All types/protocols */ if (array[i] == 0xffffffff || array[i] == ALL_TYPES) continue; printf("{ "); for (j = 0; j < count; j++) { const char *type; if (array[i] & (1 << j)) { type = sock_types[j].name; if (type) printf("%s ", type); else printf("#%u ", j); } } if (array[i] & mask) printf("#%x ", array[i] & mask); printf("} "); } } printf("\n"); } apparmor-2.13.3/parser/apparmor.70000644000175000017500000002650213502024374014423 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "APPARMOR 7" .TH APPARMOR 7 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" AppArmor \- kernel enhancement to confine programs to a limited set of resources. .SH "DESCRIPTION" .IX Header "DESCRIPTION" AppArmor is a kernel enhancement to confine programs to a limited set of resources. AppArmor's unique security model is to bind access control attributes to programs rather than to users. .PP AppArmor confinement is provided via \fIprofiles\fR loaded into the kernel via \fIapparmor_parser\fR\|(8), typically through the \fI/etc/init.d/apparmor\fR SysV initscript, which is used like this: .PP .Vb 3 \& # /etc/init.d/apparmor start \& # /etc/init.d/apparmor stop \& # /etc/init.d/apparmor restart .Ve .PP AppArmor can operate in two modes: \fIenforcement\fR, and \fIcomplain or learning\fR: .IP "\(bu" 4 \&\fIenforcement\fR \- Profiles loaded in enforcement mode will result in enforcement of the policy defined in the profile as well as reporting policy violation attempts to syslogd. .IP "\(bu" 4 \&\fIcomplain\fR \- Profiles loaded in \f(CW\*(C`complain\*(C'\fR mode will not enforce policy. Instead, it will report policy violation attempts. This mode is convenient for developing profiles. To manage complain mode for individual profiles the utilities \fIaa\-complain\fR\|(8) and \fIaa\-enforce\fR\|(8) can be used. These utilities take a program name as an argument. .PP Profiles are traditionally stored in files in \fI/etc/apparmor.d/\fR under filenames with the convention of replacing the \fB/\fR in pathnames with \fB.\fR (except for the root \fB/\fR) so profiles are easier to manage (e.g. the \fI/usr/sbin/nscd\fR profile would be named \fIusr.sbin.nscd\fR). .PP Profiles are applied to a process at \fIexec\fR\|(3) time (as seen through the \&\fIexecve\fR\|(2) system call): once a profile is loaded for a program, that program will be confined on the next \fIexec\fR\|(3). If a process is already running under a profile, when one replaces that profile in the kernel, the updated profile is applied immediately to that process. On the other hand, a process that is already running unconfined cannot be confined. .PP AppArmor supports the Linux kernel's securityfs filesystem, and makes available the list of the profiles currently loaded; to mount the filesystem: .PP .Vb 5 \& # mount \-tsecurityfs securityfs /sys/kernel/security \& $ cat /sys/kernel/security/apparmor/profiles \& /usr/bin/mutt \& /usr/bin/gpg \& ... .Ve .PP Normally, the initscript will mount securityfs if it has not already been done. .PP AppArmor also restricts what privileged operations a confined process may execute, even if the process is running as root. A confined process cannot call the following system calls: .PP .Vb 3 \& create_module(2) delete_module(2) init_module(2) ioperm(2) \& iopl(2) ptrace(2) reboot(2) setdomainname(2) \& sethostname(2) swapoff(2) swapon(2) sysctl(2) .Ve .SH "ERRORS" .IX Header "ERRORS" When a confined process tries to access a file it does not have permission to access, the kernel will report a message through audit, similar to: .PP .Vb 3 \& audit(1386511672.612:238): apparmor="DENIED" operation="exec" \& parent=7589 profile="/tmp/sh" name="/bin/uname" pid=7605 \& comm="sh" requested_mask="x" denied_mask="x" fsuid=0 ouid=0 \& \& audit(1386511672.613:239): apparmor="DENIED" operation="open" \& parent=7589 profile="/tmp/sh" name="/bin/uname" pid=7605 \& comm="sh" requested_mask="r" denied_mask="r" fsuid=0 ouid=0 \& \& audit(1386511772.804:246): apparmor="DENIED" operation="capable" \& parent=7246 profile="/tmp/sh" pid=7589 comm="sh" pid=7589 \& comm="sh" capability=2 capname="dac_override" .Ve .PP The permissions requested by the process are described in the operation= and denied_mask= (for files \- capabilities etc. use a slightly different log format). The \*(L"name\*(R" and process id of the running program are reported, as well as the profile name including any \*(L"hat\*(R" that may be active, separated by \*(L"//\*(R". (\*(L"Name\*(R" is in quotes, because the process name is limited to 15 bytes; it is the same as reported through the Berkeley process accounting.) .PP For confined processes running under a profile that has been loaded in complain mode, enforcement will not take place and the log messages reported to audit will be of the form: .PP .Vb 3 \& audit(1386512577.017:275): apparmor="ALLOWED" operation="open" \& parent=8012 profile="/usr/bin/du" name="/etc/apparmor.d/tunables/" \& pid=8049 comm="du" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0 \& \& audit(1386512577.017:276): apparmor="ALLOWED" operation="open" \& parent=8012 profile="/usr/bin/du" name="/etc/apparmor.d/tunables/" \& pid=8049 comm="du" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0 .Ve .PP If the userland auditd is not running, the kernel will send audit events to klogd; klogd will send the messages to syslog, which will log the messages with the \s-1KERN\s0 facility. Thus, \s-1REJECTING\s0 and \s-1PERMITTING\s0 messages may go to either \fI/var/log/audit/audit.log\fR or \fI/var/log/messages\fR, depending upon local configuration. .SH "DEBUGGING" .IX Header "DEBUGGING" AppArmor provides a few facilities to log more information, which can help debugging profiles. .SS "Enable debug mode" .IX Subsection "Enable debug mode" When debug mode is enabled, AppArmor will log a few extra messages to dmesg (not via the audit subsystem). For example, the logs will tell whether environment scrubbing has been applied. .PP To enable debug mode, run: .PP .Vb 1 \& echo 1 > /sys/module/apparmor/parameters/debug .Ve .SS "Turn off deny audit quieting" .IX Subsection "Turn off deny audit quieting" By default, operations that trigger \f(CW\*(C`deny\*(C'\fR rules are not logged. This is called \fIdeny audit quieting\fR. .PP To turn off deny audit quieting, run: .PP .Vb 1 \& echo \-n noquiet >/sys/module/apparmor/parameters/audit .Ve .SS "Force audit mode" .IX Subsection "Force audit mode" AppArmor can log a message for every operation that triggers a rule configured in the policy. This is called \fIforce audit mode\fR. .PP \&\fBWarning!\fR Force audit mode can be extremely noisy even for a single profile, let alone when enabled globally. .PP To set a specific profile in force audit mode, add the \f(CW\*(C`audit\*(C'\fR flag: .PP .Vb 1 \& profile foo flags=(audit) { ... } .Ve .PP To enable force audit mode globally, run: .PP .Vb 1 \& echo \-n all > /sys/module/apparmor/parameters/audit .Ve .PP If auditd is not running, to avoid losing too many of the extra log messages, you will likely have to turn off rate limiting by doing: .PP .Vb 1 \& echo 0 > /proc/sys/kernel/printk_ratelimit .Ve .PP But even then the kernel ring buffer may overflow and you might lose messages. .PP Else, if auditd is running, see \fIauditd\fR\|(8) and \fIauditd.conf\fR\|(5). .SH "FILES" .IX Header "FILES" .IP "\fI/etc/init.d/apparmor\fR" 4 .IX Item "/etc/init.d/apparmor" .PD 0 .IP "\fI/etc/apparmor.d/\fR" 4 .IX Item "/etc/apparmor.d/" .IP "\fI/var/lib/apparmor/\fR" 4 .IX Item "/var/lib/apparmor/" .IP "\fI/var/log/audit/audit.log\fR" 4 .IX Item "/var/log/audit/audit.log" .IP "\fI/var/log/messages\fR" 4 .IX Item "/var/log/messages" .PD .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor_parser\fR\|(8), \fIaa_change_hat\fR\|(2), \fIapparmor.d\fR\|(5), \&\fIsubdomain.conf\fR\|(5), \fIaa\-autodep\fR\|(1), \fIclean\fR\|(1), \&\fIauditd\fR\|(8), \&\fIaa\-unconfined\fR\|(8), \fIaa\-enforce\fR\|(1), \fIaa\-complain\fR\|(1), and . apparmor-2.13.3/parser/apparmor.systemd0000644000175000017500000000333713502024172015742 0ustar jjjj#!/bin/sh # ---------------------------------------------------------------------- # Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Novell, Inc. # ---------------------------------------------------------------------- APPARMOR_FUNCTIONS=/lib/apparmor/rc.apparmor.functions aa_action() { echo "$1" shift "$@" return $? } aa_log_warning_msg() { echo "Warning: $*" } aa_log_failure_msg() { echo "Error: $*" } aa_log_action_start() { echo "$@" } aa_log_action_end() { printf "" } aa_log_daemon_msg() { echo "$@" } aa_log_skipped_msg() { echo "Skipped: $*" } aa_log_end_msg() { printf "" } # source apparmor function library if [ -f "${APPARMOR_FUNCTIONS}" ]; then # shellcheck source=rc.apparmor.functions . "${APPARMOR_FUNCTIONS}" else aa_log_failure_msg "Unable to find AppArmor initscript functions" exit 1 fi case "$1" in start) apparmor_start rc=$? ;; stop) apparmor_stop rc=$? ;; restart|reload|force-reload) apparmor_restart rc=$? ;; try-restart) apparmor_try_restart rc=$? ;; kill) apparmor_kill rc=$? ;; status) apparmor_status rc=$? ;; *) exit 1 ;; esac exit "$rc" apparmor-2.13.3/parser/techdoc.toc0000644000175000017500000000515713502024374014635 0ustar jjjj\contentsline {section}{\numberline {1}Introduction}{2}{section.1} \contentsline {section}{\numberline {2}Overview}{2}{section.2} \contentsline {section}{\numberline {3}The AppArmor Security Model}{3}{section.3} \contentsline {subsection}{\numberline {3.1}Symbolic Links}{3}{subsection.3.1} \contentsline {subsection}{\numberline {3.2}Namespaces}{4}{subsection.3.2} \contentsline {subsection}{\numberline {3.3}Disconnected Files and Pseudo File Systems}{4}{subsection.3.3} \contentsline {subsection}{\numberline {3.4}Mount}{5}{subsection.3.4} \contentsline {subsection}{\numberline {3.5}The Kernel NFS Daemon}{5}{subsection.3.5} \contentsline {subsection}{\numberline {3.6}Why are the computed pathnames meaningful?}{5}{subsection.3.6} \contentsline {subsection}{\numberline {3.7}Path Permission Checking}{6}{subsection.3.7} \contentsline {subsection}{\numberline {3.8}Profile Permissions}{7}{subsection.3.8} \contentsline {subsection}{\numberline {3.9}System Calls Taking File Handles, At System Calls}{8}{subsection.3.9} \contentsline {subsection}{\numberline {3.10}File Descriptor Passing and Revalidation}{8}{subsection.3.10} \contentsline {subsection}{\numberline {3.11}Deleted Files}{8}{subsection.3.11} \contentsline {subsection}{\numberline {3.12}The access System Call}{9}{subsection.3.12} \contentsline {subsection}{\numberline {3.13}The ptrace System Call}{9}{subsection.3.13} \contentsline {subsection}{\numberline {3.14}Secure Execution}{9}{subsection.3.14} \contentsline {subsection}{\numberline {3.15}Exec Mode Merging in Profiles, Exact Matches}{10}{subsection.3.15} \contentsline {subsection}{\numberline {3.16}Capabilities}{10}{subsection.3.16} \contentsline {subsection}{\numberline {3.17}The sysctl System Call and /proc/sys}{10}{subsection.3.17} \contentsline {subsection}{\numberline {3.18}Subprofiles aka. Hats}{10}{subsection.3.18} \contentsline {subsection}{\numberline {3.19}Association of Profiles with Processes}{11}{subsection.3.19} \contentsline {subsection}{\numberline {3.20}Profile Loading, Replacement, and Removal}{11}{subsection.3.20} \contentsline {section}{\numberline {4}AppArmor Walk-Through}{12}{section.4} \contentsline {subsection}{\numberline {4.1}Kernel Patches and Configuration}{12}{subsection.4.1} \contentsline {subsection}{\numberline {4.2}The securityfs file system}{13}{subsection.4.2} \contentsline {subsection}{\numberline {4.3}Profile Loading}{13}{subsection.4.3} \contentsline {subsection}{\numberline {4.4}Anatomy of a Profile}{13}{subsection.4.4} \contentsline {subsection}{\numberline {4.5}Logging}{15}{subsection.4.5} \contentsline {subsection}{\numberline {4.6}Generating Profiles By Hand}{15}{subsection.4.6} apparmor-2.13.3/parser/parser_yacc.y0000644000175000017500000012066713502024172015202 0ustar jjjj%{ /* * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 * NOVELL (All rights reserved) * Copyright (c) 2010-2012 * Canonical Ltd. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Canonical, Ltd. */ #define YYERROR_VERBOSE 1 #include #include #include #include #include #include #include #include #include /* #define DEBUG */ #include "parser.h" #include "profile.h" #include "mount.h" #include "dbus.h" #include "af_unix.h" #include "parser_include.h" #include #include #include #include #ifndef CAP_AUDIT_WRITE #define CAP_AUDIT_WRITE 29 #endif #ifndef CAP_AUDIT_CONTROL #define CAP_AUDIT_CONTROL 30 #endif #ifndef CAP_SETFCAP #define CAP_SETFCAP 31 #endif #ifndef CAP_MAC_OVERRIDE #define CAP_MAC_OVERRIDE 32 #endif #define CIDR_32 htonl(0xffffffff) #define CIDR_24 htonl(0xffffff00) #define CIDR_16 htonl(0xffff0000) #define CIDR_8 htonl(0xff000000) /* undefine linux/capability.h CAP_TO_MASK */ #ifdef CAP_TO_MASK #undef CAP_TO_MASK #endif #define CAP_TO_MASK(x) (1ull << (x)) #define EXEC_MODE_EMPTY 0 #define EXEC_MODE_UNSAFE 1 #define EXEC_MODE_SAFE 2 int parser_token = 0; struct cod_entry *do_file_rule(char *id, int mode, char *link_id, char *nt); mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src, struct cond_entry *dst_conds, char *dst, int mode); mnt_rule *do_pivot_rule(struct cond_entry *old, char *root, char *transition); void add_local_entry(Profile *prof); %} %token TOK_ID %token TOK_CONDID %token TOK_CONDLISTID %token TOK_CARET %token TOK_OPEN %token TOK_CLOSE %token TOK_MODE %token TOK_END_OF_RULE %token TOK_EQUALS %token TOK_ARROW %token TOK_ADD_ASSIGN %token TOK_LE %token TOK_SET_VAR %token TOK_BOOL_VAR %token TOK_VALUE %token TOK_IF %token TOK_ELSE %token TOK_NOT %token TOK_DEFINED %token TOK_CHANGE_PROFILE %token TOK_NETWORK %token TOK_UNIX %token TOK_CREATE %token TOK_SHUTDOWN %token TOK_ACCEPT %token TOK_CONNECT %token TOK_LISTEN %token TOK_SETOPT %token TOK_GETOPT %token TOK_SETATTR %token TOK_GETATTR %token TOK_HAT %token TOK_UNSAFE %token TOK_SAFE %token TOK_COLON %token TOK_LINK %token TOK_OWNER %token TOK_OTHER %token TOK_SUBSET %token TOK_AUDIT %token TOK_DENY %token TOK_ALLOW %token TOK_PROFILE %token TOK_SET %token TOK_ALIAS %token TOK_PTRACE %token TOK_OPENPAREN %token TOK_CLOSEPAREN %token TOK_COMMA %token TOK_FILE %token TOK_MOUNT %token TOK_REMOUNT %token TOK_UMOUNT %token TOK_PIVOTROOT %token TOK_IN %token TOK_DBUS %token TOK_SIGNAL %token TOK_SEND %token TOK_RECEIVE %token TOK_BIND %token TOK_READ %token TOK_WRITE %token TOK_EAVESDROP %token TOK_PEER %token TOK_TRACE %token TOK_TRACEDBY %token TOK_READBY %token TOK_ABI /* rlimits */ %token TOK_RLIMIT %token TOK_SOFT_RLIMIT %token TOK_RLIMIT_CPU %token TOK_RLIMIT_FSIZE %token TOK_RLIMIT_DATA %token TOK_RLIMIT_STACK %token TOK_RLIMIT_CORE %token TOK_RLIMIT_RSS %token TOK_RLIMIT_NOFILE %token TOK_RLIMIT_OFILE %token TOK_RLIMIT_AS %token TOK_RLIMIT_NPROC %token TOK_RLIMIT_MEMLOCK %token TOK_RLIMIT_LOCKS %token TOK_RLIMIT_SIGPENDING %token TOK_RLIMIT_MSGQUEUE %token TOK_RLIMIT_NICE %token TOK_RLIMIT_RTPRIO /* capabilities */ %token TOK_CAPABILITY /* debug flag values */ %token TOK_FLAGS %code requires { #include "parser.h" #include "profile.h" #include "mount.h" #include "dbus.h" #include "signal.h" #include "ptrace.h" #include "af_unix.h" } %union { char *id; char *flag_id; char *mode; struct aa_network_entry *network_entry; Profile *prof; struct cod_net_entry *net_entry; struct cod_entry *user_entry; mnt_rule *mnt_entry; dbus_rule *dbus_entry; signal_rule *signal_entry; ptrace_rule *ptrace_entry; unix_rule *unix_entry; flagvals flags; int fmode; uint64_t cap; unsigned int allowed_protocol; char *set_var; char *bool_var; char *var_val; struct value_list *val_list; struct cond_entry *cond_entry; struct cond_entry_list cond_entry_list; int boolean; struct prefixes prefix; } %type TOK_ID %type TOK_CONDID %type TOK_CONDLISTID %type TOK_MODE %type file_mode %type profile_base %type profile %type rules %type hat %type local_profile %type cond_rule %type network_rule %type rule %type file_rule %type file_rule_tail %type link_rule %type frule %type mnt_rule %type opt_conds %type cond %type cond_list %type opt_cond_list %type flags %type flagvals %type flagval %type caps %type capability %type change_profile %type TOK_SET_VAR %type TOK_BOOL_VAR %type TOK_VALUE %type valuelist %type expr %type id_or_var %type opt_id_or_var %type opt_subset_flag %type opt_audit_flag %type opt_owner_flag %type opt_profile_flag %type opt_flags %type opt_perm_mode %type opt_id %type opt_prefix %type dbus_perm %type dbus_perms %type opt_dbus_perm %type dbus_rule %type signal_perm %type signal_perms %type opt_signal_perm %type signal_rule %type ptrace_perm %type ptrace_perms %type opt_ptrace_perm %type ptrace_rule %type net_perm %type net_perms %type opt_net_perm %type unix_rule %type opt_target %type opt_named_transition %type opt_exec_mode %type opt_file %% list: preamble profilelist { /* nothing */ }; profilelist: { /* nothing */ }; profilelist: profilelist profile { PDEBUG("Matched: list profile\n"); add_to_list($2); }; opt_profile_flag: { /* nothing */ $$ = 0; } | TOK_PROFILE { $$ = 1; } | hat_start { $$ = 2; } opt_id: { /* nothing */ $$ = NULL; } | TOK_ID { $$ = $1; } opt_id_or_var: { /* nothing */ $$ = NULL; } | id_or_var { $$ = $1; } profile_base: TOK_ID opt_id_or_var flags TOK_OPEN rules TOK_CLOSE { Profile *prof = $5; bool self_stack = false; if (!prof) { yyerror(_("Memory allocation error.")); } parse_label(&self_stack, &prof->ns, &prof->name, $1, true); free($1); if (self_stack) { yyerror(_("Profile names must begin with a '/' or a namespace")); } /* Honor the --namespace-string command line option */ if (profile_ns) { /** * Print warning if the profile specified a namespace * different than the one specified with the * --namespace-string command line option */ if (prof->ns && strcmp(prof->ns, profile_ns)) pwarn("%s: -n %s overriding policy specified namespace :%s:\n", progname, profile_ns, prof->ns); free(prof->ns); prof->ns = strdup(profile_ns); if (!prof->ns) yyerror(_("Memory allocation error.")); } prof->attachment = $2; if ($2 && !($2[0] == '/' || strncmp($2, "@{", 2) == 0)) yyerror(_("Profile attachment must begin with a '/' or variable.")); prof->flags = $3; if (force_complain && kernel_abi_version == 5) /* newer abis encode force complain as part of the * header */ prof->flags.complain = 1; post_process_file_entries(prof); post_process_rule_entries(prof); PDEBUG("%s: flags='%s%s'\n", $2, prof->flags.complain ? "complain, " : "", prof->flags.audit ? "audit" : ""); $$ = prof; }; profile: opt_profile_flag profile_base { Profile *prof = $2; if ($2->ns) PDEBUG("Matched: :%s://%s { ... }\n", $2->ns, $2->name); else PDEBUG("Matched: %s { ... }\n", $2->name); if ($2->name[0] != '/' && !($1 || $2->ns)) yyerror(_("Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'.")); if ($1 == 2) prof->flags.hat = 1; $$ = prof; }; local_profile: TOK_PROFILE profile_base { Profile *prof = $2; if ($2) PDEBUG("Matched: local profile %s { ... }\n", prof->name); prof->local = 1; $$ = prof; }; hat: hat_start profile_base { Profile *prof = $2; if ($2) PDEBUG("Matched: hat %s { ... }\n", prof->name); prof->flags.hat = 1; $$ = prof; }; preamble: { /* nothing */ } | preamble alias { /* nothing */ }; | preamble varassign { /* nothing */ }; | preamble abi_rule { /* nothing */ }; alias: TOK_ALIAS TOK_ID TOK_ARROW TOK_ID TOK_END_OF_RULE { if (!new_alias($2, $4)) yyerror(_("Failed to create alias %s -> %s\n"), $2, $4); free($2); free($4); }; varassign: TOK_SET_VAR TOK_EQUALS valuelist { struct value_list *list = $3; char *var_name = process_var($1); int err; if (!list || !list->value) yyerror("Assert: valuelist returned NULL"); PDEBUG("Matched: set assignment for (%s)\n", $1); err = new_set_var(var_name, list->value); if (err) { free(var_name); yyerror("variable %s was previously declared", $1); /* FIXME: it'd be handy to report the previous location */ } for (list = list->next; list; list = list->next) { err = add_set_value(var_name, list->value); if (err) { free(var_name); yyerror("Error adding %s to set var %s", list->value, $1); } } free_value_list($3); free(var_name); free($1); } varassign: TOK_SET_VAR TOK_ADD_ASSIGN valuelist { struct value_list *list = $3; char *var_name = process_var($1); int err; if (!list || !list->value) yyerror("Assert: valuelist returned NULL"); PDEBUG("Matched: additive assignment for (%s)\n", $1); /* do the first one outside the loop, subsequent * failures are indicative of symtab failures */ err = add_set_value(var_name, list->value); if (err) { free(var_name); yyerror("variable %s was not previously declared, but is being assigned additional values", $1); } for (list = list->next; list; list = list->next) { err = add_set_value(var_name, list->value); if (err) { free(var_name); yyerror("Error adding %s to set var %s", list->value, $1); } } free_value_list($3); free(var_name); free($1); } varassign: TOK_BOOL_VAR TOK_EQUALS TOK_VALUE { int boolean, err; char *var_name = process_var($1); PDEBUG("Matched: boolean assignment (%s) to %s\n", $1, $3); boolean = str_to_boolean($3); if (boolean == -1) { yyerror("Invalid boolean assignment for (%s): %s is not true or false", $1, $3); } err = add_boolean_var(var_name, boolean); free(var_name); if (err) { yyerror("variable %s was previously declared", $1); /* FIXME: it'd be handy to report the previous location */ } free($1); free($3); } valuelist: TOK_VALUE { struct value_list *val = new_value_list($1); if (!val) yyerror(_("Memory allocation error.")); PDEBUG("Matched: value (%s)\n", $1); $$ = val; } valuelist: valuelist TOK_VALUE { struct value_list *val = new_value_list($2); if (!val) yyerror(_("Memory allocation error.")); PDEBUG("Matched: value list\n"); list_append($1, val); $$ = $1; } flags: { /* nothing */ flagvals fv = { 0, 0, 0, 0 }; $$ = fv; }; opt_flags: { /* nothing */ $$ = 0; } | TOK_CONDID TOK_EQUALS { if (strcmp($1, "flags") != 0) yyerror("expected flags= got %s=", $1); free($1); $$ = 1; } flags: opt_flags TOK_OPENPAREN flagvals TOK_CLOSEPAREN { $$ = $3; }; flagvals: flagvals flagval { $1.complain = $1.complain || $2.complain; $1.audit = $1.audit || $2.audit; $1.path = $1.path | $2.path; if (($1.path & (PATH_CHROOT_REL | PATH_NS_REL)) == (PATH_CHROOT_REL | PATH_NS_REL)) yyerror(_("Profile flag chroot_relative conflicts with namespace_relative")); if (($1.path & (PATH_MEDIATE_DELETED | PATH_DELEGATE_DELETED)) == (PATH_MEDIATE_DELETED | PATH_DELEGATE_DELETED)) yyerror(_("Profile flag mediate_deleted conflicts with delegate_deleted")); if (($1.path & (PATH_ATTACH | PATH_NO_ATTACH)) == (PATH_ATTACH | PATH_NO_ATTACH)) yyerror(_("Profile flag attach_disconnected conflicts with no_attach_disconnected")); if (($1.path & (PATH_CHROOT_NSATTACH | PATH_CHROOT_NO_ATTACH)) == (PATH_CHROOT_NSATTACH | PATH_CHROOT_NO_ATTACH)) yyerror(_("Profile flag chroot_attach conflicts with chroot_no_attach")); $$ = $1; }; flagvals: flagval { $$ = $1; }; flagval: TOK_VALUE { flagvals fv = { 0, 0, 0, 0 }; if (strcmp($1, "debug") == 0) { yyerror(_("Profile flag 'debug' is no longer valid.")); } else if (strcmp($1, "complain") == 0) { fv.complain = 1; } else if (strcmp($1, "audit") == 0) { fv.audit = 1; } else if (strcmp($1, "chroot_relative") == 0) { fv.path |= PATH_CHROOT_REL; } else if (strcmp($1, "namespace_relative") == 0) { fv.path |= PATH_NS_REL; } else if (strcmp($1, "mediate_deleted") == 0) { fv.path |= PATH_MEDIATE_DELETED; } else if (strcmp($1, "delegate_deleted") == 0) { fv.path |= PATH_DELEGATE_DELETED; } else if (strcmp($1, "attach_disconnected") == 0) { fv.path |= PATH_ATTACH; } else if (strcmp($1, "no_attach_disconnected") == 0) { fv.path |= PATH_NO_ATTACH; } else if (strcmp($1, "chroot_attach") == 0) { fv.path |= PATH_CHROOT_NSATTACH; } else if (strcmp($1, "chroot_no_attach") == 0) { fv.path |= PATH_CHROOT_NO_ATTACH; } else { yyerror(_("Invalid profile flag: %s."), $1); } free($1); $$ = fv; }; opt_subset_flag: { /* nothing */ $$ = 0; } | TOK_SUBSET { $$ = 1; } | TOK_LE { $$ = 1; } opt_audit_flag: { /* nothing */ $$ = 0; } | TOK_AUDIT { $$ = 1; }; opt_owner_flag: { /* nothing */ $$ = 0; } | TOK_OWNER { $$ = 1; }; | TOK_OTHER { $$ = 2; }; opt_perm_mode: { /* nothing */ $$ = 0; } | TOK_ALLOW { $$ = 0; } | TOK_DENY { $$ = 1; } opt_prefix: opt_audit_flag opt_perm_mode opt_owner_flag { $$.audit = $1; $$.deny = $2; $$.owner = $3; } rules: { /* nothing */ Profile *prof = new Profile(); if (!prof) { yyerror(_("Memory allocation error.")); } $$ = prof; }; rules: rules abi_rule { /* nothing */ } rules: rules opt_prefix rule { PDEBUG("matched: rules rule\n"); PDEBUG("rules rule: (%s)\n", $3->name); if (!$3) yyerror(_("Assert: `rule' returned NULL.")); $3->deny = $2.deny; if (($2.deny && ($3->mode & AA_EXEC_BITS) && ($3->mode & ALL_AA_EXEC_TYPE))) yyerror(_("Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'")); else if (!$2.deny && ($3->mode & AA_EXEC_BITS) && !($3->mode & ALL_AA_EXEC_TYPE) && !($3->nt_name)) yyerror(_("Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'")); if ($2.owner == 1) $3->mode &= (AA_USER_PERMS | AA_SHARED_PERMS); else if ($2.owner == 2) $3->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS); /* only set audit ctl quieting if the rule is not audited */ if (($2.deny && !$2.audit) || (!$2.deny && $2.audit)) $3->audit = $3->mode & ~ALL_AA_EXEC_TYPE; add_entry_to_policy($1, $3); $$ = $1; }; rules: rules opt_prefix TOK_OPEN rules TOK_CLOSE { struct cod_entry *entry, *tmp; if ($2.deny) yyerror(_("deny prefix not allowed")); PDEBUG("matched: %s%s%sblock\n", $2.audit ? "audit " : "", $2.deny ? "deny " : "", $2.owner ? "owner " : ""); list_for_each_safe($4->entries, entry, tmp) { entry->next = NULL; if (entry->mode & AA_EXEC_BITS) { if (entry->deny && (entry->mode & ALL_AA_EXEC_TYPE)) yyerror(_("Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'")); else if (!entry->deny && !(entry->mode & ALL_AA_EXEC_TYPE)) yyerror(_("Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'")); } if ($2.owner == 1) entry->mode &= (AA_USER_PERMS | AA_SHARED_PERMS); else if ($2.owner == 2) entry->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS); if ($2.audit && !entry->deny) entry->audit = entry->mode & ~ALL_AA_EXEC_TYPE; else if (!$2.audit && entry->deny) entry->audit = entry->mode & ~ALL_AA_EXEC_TYPE; add_entry_to_policy($1, entry); } $4->entries = NULL; // fix me transfer rules and free sub profile delete $4; $$ = $1; }; rules: rules opt_prefix network_rule { struct aa_network_entry *entry, *tmp; PDEBUG("Matched: network rule\n"); if ($2.owner) yyerror(_("owner prefix not allowed")); if (!$3) yyerror(_("Assert: `network_rule' return invalid protocol.")); if (!$1->alloc_net_table()) yyerror(_("Memory allocation error.")); list_for_each_safe($3, entry, tmp) { /* map to extended mediation if available */ if (entry->family == AF_UNIX && kernel_supports_unix) { unix_rule *rule = new unix_rule(entry->type, $2.audit, $2.deny); if (!rule) yyerror(_("Memory allocation error.")); $1->rule_ents.push_back(rule); } if (entry->type > SOCK_PACKET) { /* setting mask instead of a bit */ if ($2.deny) { $1->net.deny[entry->family] |= entry->type; if (!$2.audit) $1->net.quiet[entry->family] |= entry->type; } else { $1->net.allow[entry->family] |= entry->type; if ($2.audit) $1->net.audit[entry->family] |= entry->type; } } else { if ($2.deny) { $1->net.deny[entry->family] |= 1 << entry->type; if (!$2.audit) $1->net.quiet[entry->family] |= 1 << entry->type; } else { $1->net.allow[entry->family] |= 1 << entry->type; if ($2.audit) $1->net.audit[entry->family] |= 1 << entry->type; } } free(entry); } $$ = $1; } rules: rules opt_prefix mnt_rule { if ($2.owner) yyerror(_("owner prefix not allowed on mount rules")); if ($2.deny && $2.audit) { $3->deny = 1; } else if ($2.deny) { $3->deny = 1; $3->audit = $3->allow; } else if ($2.audit) { $3->audit = $3->allow; } $1->rule_ents.push_back($3); $$ = $1; } rules: rules opt_prefix dbus_rule { if ($2.owner) yyerror(_("owner prefix not allowed on dbus rules")); if ($2.deny && $2.audit) { $3->deny = 1; } else if ($2.deny) { $3->deny = 1; $3->audit = $3->mode; } else if ($2.audit) { $3->audit = $3->mode; } $1->rule_ents.push_back($3); $$ = $1; } rules: rules opt_prefix signal_rule { if ($2.owner) yyerror(_("owner prefix not allowed on signal rules")); if ($2.deny && $2.audit) { $3->deny = 1; } else if ($2.deny) { $3->deny = 1; $3->audit = $3->mode; } else if ($2.audit) { $3->audit = $3->mode; } $1->rule_ents.push_back($3); $$ = $1; } rules: rules opt_prefix ptrace_rule { if ($2.owner) yyerror(_("owner prefix not allowed on ptrace rules")); if ($2.deny && $2.audit) { $3->deny = 1; } else if ($2.deny) { $3->deny = 1; $3->audit = $3->mode; } else if ($2.audit) { $3->audit = $3->mode; } $1->rule_ents.push_back($3); $$ = $1; } rules: rules opt_prefix unix_rule { if ($2.owner) yyerror(_("owner prefix not allowed on unix rules")); if ($2.deny && $2.audit) { $3->deny = 1; } else if ($2.deny) { $3->deny = 1; $3->audit = $3->mode; } else if ($2.audit) { $3->audit = $3->mode; } $1->rule_ents.push_back($3); $$ = $1; } rules: rules opt_prefix change_profile { PDEBUG("matched: rules change_profile\n"); PDEBUG("rules change_profile: (%s)\n", $3->name); if (!$3) yyerror(_("Assert: `change_profile' returned NULL.")); if ($2.owner) yyerror(_("owner prefix not allowed on unix rules")); if ($2.deny && $2.audit) { $3->deny = 1; } else if ($2.deny) { $3->deny = 1; $3->audit = $3->mode; } else if ($2.audit) { $3->audit = $3->mode; } add_entry_to_policy($1, $3); $$ = $1; }; rules: rules opt_prefix capability { if ($2.owner) yyerror(_("owner prefix not allowed on capability rules")); if ($2.deny && $2.audit) { $1->caps.deny |= $3; } else if ($2.deny) { $1->caps.deny |= $3; $1->caps.quiet |= $3; } else { $1->caps.allow |= $3; if ($2.audit) $1->caps.audit |= $3; } $$ = $1; }; rules: rules hat { PDEBUG("Matched: hat rule\n"); if (!$2) yyerror(_("Assert: 'hat rule' returned NULL.")); add_hat_to_policy($1, $2); $$ = $1; }; rules: rules local_profile { PDEBUG("Matched: hat rule\n"); if (!$2) yyerror(_("Assert: 'local_profile rule' returned NULL.")); add_hat_to_policy($1, $2); add_local_entry($2); $$ = $1; }; rules: rules cond_rule { PDEBUG("Matched: conditional rules\n"); $$ = merge_policy($1, $2); } rules: rules TOK_SET TOK_RLIMIT TOK_ID TOK_LE TOK_VALUE opt_id TOK_END_OF_RULE { rlim_t value = RLIM_INFINITY; long long tmp; char *end; int limit = get_rlimit($4); if (limit == -1) yyerror("INVALID RLIMIT '%s'\n", $4); if (strcmp($6, "infinity") == 0) { value = RLIM_INFINITY; } else { const char *kb = "KB"; const char *mb = "MB"; const char *gb = "GB"; tmp = strtoll($6, &end, 0); switch (limit) { case RLIMIT_CPU: if (!end || $6 == end || tmp < 0) yyerror("RLIMIT '%s' invalid value %s\n", $4, $6); tmp = convert_time_units(tmp, SECONDS_P_MS, $7); if (tmp == -1LL) yyerror("RLIMIT '%s %s' < minimum value of 1s\n", $4, $6); else if (tmp < 0LL) yyerror("RLIMIT '%s' invalid value %s\n", $4, $6); if (!$7) pwarn(_("RLIMIT 'cpu' no units specified using default units of seconds\n")); value = tmp; break; #ifdef RLIMIT_RTTIME case RLIMIT_RTTIME: /* RTTIME is measured in microseconds */ if (!end || $6 == end || tmp < 0) yyerror("RLIMIT '%s' invalid value %s %s\n", $4, $6, $7 ? $7 : ""); tmp = convert_time_units(tmp, 1LL, $7); if (tmp < 0LL) yyerror("RLIMIT '%s' invalid value %s %s\n", $4, $6, $7 ? $7 : ""); if (!$7) pwarn(_("RLIMIT 'rttime' no units specified using default units of microseconds\n")); value = tmp; break; #endif case RLIMIT_NOFILE: case RLIMIT_NPROC: case RLIMIT_LOCKS: case RLIMIT_SIGPENDING: #ifdef RLIMIT_RTPRIO case RLIMIT_RTPRIO: if (!end || $6 == end || $7 || tmp < 0) yyerror("RLIMIT '%s' invalid value %s %s\n", $4, $6, $7 ? $7 : ""); value = tmp; break; #endif #ifdef RLIMIT_NICE case RLIMIT_NICE: if (!end || $6 == end || $7) yyerror("RLIMIT '%s' invalid value %s %s\n", $4, $6, $7 ? $7 : ""); if (tmp < -20 || tmp > 19) yyerror("RLIMIT '%s' out of range (-20 .. 19) %d\n", $4, tmp); value = tmp + 20; break; #endif case RLIMIT_FSIZE: case RLIMIT_DATA: case RLIMIT_STACK: case RLIMIT_CORE: case RLIMIT_RSS: case RLIMIT_AS: case RLIMIT_MEMLOCK: case RLIMIT_MSGQUEUE: if ($6 == end || tmp < 0) yyerror("RLIMIT '%s' invalid value %s %s\n", $4, $6, $7 ? $7 : ""); if (!$7) { ; /* use default of bytes */ } else if (strstr(kb, $7) == kb) { tmp *= 1024; } else if (strstr(mb, $7) == mb) { tmp *= 1024*1024; } else if (strstr(gb, $7) == gb) { tmp *= 1024*1024*1024; } else { yyerror("RLIMIT '%s' invalid value %s %s\n", $4, $6, $7); } value = tmp; break; default: yyerror("Unknown RLIMIT %d\n", $4); } } $1->rlimits.specified |= 1 << limit; $1->rlimits.limits[limit] = value; free($4); free($6); $$ = $1; }; cond_rule: TOK_IF expr TOK_OPEN rules TOK_CLOSE { Profile *ret = NULL; PDEBUG("Matched: found conditional rules\n"); if ($2) { ret = $4; } else { delete $4; } $$ = ret; } cond_rule: TOK_IF expr TOK_OPEN rules TOK_CLOSE TOK_ELSE TOK_OPEN rules TOK_CLOSE { Profile *ret = NULL; PDEBUG("Matched: found conditional else rules\n"); if ($2) { ret = $4; delete $8; } else { ret = $8; delete $4; } $$ = ret; } cond_rule: TOK_IF expr TOK_OPEN rules TOK_CLOSE TOK_ELSE cond_rule { Profile *ret = NULL; PDEBUG("Matched: found conditional else-if rules\n"); if ($2) { ret = $4; delete $7; } else { ret = $7; delete $4; } $$ = ret; } expr: TOK_NOT expr { $$ = !$2; } expr: TOK_BOOL_VAR { char *var_name = process_var($1); int boolean = get_boolean_var(var_name); PDEBUG("Matched: boolean expr %s value: %d\n", $1, boolean); if (boolean < 0) { /* FIXME check for set var */ yyerror(_("Unset boolean variable %s used in if-expression"), $1); } $$ = boolean; free(var_name); free($1); } expr: TOK_DEFINED TOK_SET_VAR { char *var_name = process_var($2); void *set_value = get_set_var(var_name); PDEBUG("Matched: defined set expr %s value %lx\n", $2, (long) set_value); $$ = !! (long) set_value; free(var_name); free($2); } expr: TOK_DEFINED TOK_BOOL_VAR { char *var_name = process_var($2); int boolean = get_boolean_var(var_name); PDEBUG("Matched: defined set expr %s value %d\n", $2, boolean); $$ = (boolean != -1); free(var_name); free($2); } id_or_var: TOK_ID { $$ = $1; } id_or_var: TOK_SET_VAR { $$ = $1; }; opt_target: /* nothing */ { $$ = NULL; } opt_target: TOK_ARROW id_or_var { $$ = $2; }; opt_named_transition: { /* nothing */ $$ = NULL; } | TOK_ARROW id_or_var { $$ = $2; }; rule: file_rule { $$ = $1; } | link_rule { $$ = $1; } abi_rule: TOK_ABI TOK_ID TOK_END_OF_RULE { pwarn(_("%s: Profile abi not supported, falling back to system abi.\n"), progname); free($2); }; opt_exec_mode: { /* nothing */ $$ = EXEC_MODE_EMPTY; } | TOK_UNSAFE { $$ = EXEC_MODE_UNSAFE; }; | TOK_SAFE { $$ = EXEC_MODE_SAFE; }; opt_file: { /* nothing */ $$ = 0; } | TOK_FILE { $$ = 1; } frule: id_or_var file_mode opt_named_transition TOK_END_OF_RULE { $$ = do_file_rule($1, $2, NULL, $3); }; frule: file_mode opt_subset_flag id_or_var opt_named_transition TOK_END_OF_RULE { if ($2 && ($1 & ~AA_LINK_BITS)) yyerror(_("subset can only be used with link rules.")); if ($4 && ($1 & AA_LINK_BITS) && ($1 & AA_EXEC_BITS)) yyerror(_("link and exec perms conflict on a file rule using ->")); if ($4 && label_contains_ns($4) && ($1 & AA_LINK_BITS)) yyerror(_("link perms are not allowed on a named profile transition.\n")); if (($1 & AA_LINK_BITS)) { $$ = do_file_rule($3, $1, $4, NULL); $$->subset = $2; } else { $$ = do_file_rule($3, $1, NULL, $4); } }; file_rule: TOK_FILE TOK_END_OF_RULE { char *path = strdup("/{**,}"); int perms = ((AA_BASE_PERMS & ~AA_EXEC_TYPE) | (AA_EXEC_INHERIT | AA_MAY_EXEC)); /* duplicate to other permission set */ perms |= perms << AA_OTHER_SHIFT; if (!path) yyerror(_("Memory allocation error.")); $$ = do_file_rule(path, perms, NULL, NULL); } | opt_file file_rule_tail { $$ = $2; } file_rule_tail: opt_exec_mode frule { if ($1 != EXEC_MODE_EMPTY) { if (!($2->mode & AA_EXEC_BITS)) yyerror(_("unsafe rule missing exec permissions")); if ($1 == EXEC_MODE_UNSAFE) { $2->mode |= (($2->mode & AA_EXEC_BITS) << 8) & ALL_AA_EXEC_UNSAFE; } else if ($1 == EXEC_MODE_SAFE) $2->mode &= ~ALL_AA_EXEC_UNSAFE; } $$ = $2; }; file_rule_tail: opt_exec_mode id_or_var file_mode id_or_var { /* Oopsie, we appear to be missing an EOL marker. If we * were *smart*, we could work around it. Since we're * obviously not smart, we'll just punt with a more * sensible error. */ yyerror(_("missing an end of line character? (entry: %s)"), $2); }; link_rule: TOK_LINK opt_subset_flag id_or_var TOK_ARROW id_or_var TOK_END_OF_RULE { struct cod_entry *entry; PDEBUG("Matched: link tok_id (%s) -> (%s)\n", $3, $5); entry = new_entry($3, AA_LINK_BITS, $5); entry->subset = $2; PDEBUG("rule.entry: link (%s)\n", entry->name); $$ = entry; }; network_rule: TOK_NETWORK TOK_END_OF_RULE { size_t family; struct aa_network_entry *new_entry, *entry = NULL; for (family = AF_UNSPEC; family < get_af_max(); family++) { new_entry = new_network_ent(family, 0xffffffff, 0xffffffff); if (!new_entry) yyerror(_("Memory allocation error.")); new_entry->next = entry; entry = new_entry; } $$ = entry; } network_rule: TOK_NETWORK TOK_ID TOK_END_OF_RULE { struct aa_network_entry *entry; entry = network_entry($2, NULL, NULL); if (!entry) /* test for short circuiting of family */ entry = network_entry(NULL, $2, NULL); if (!entry) yyerror(_("Invalid network entry.")); free($2); $$ = entry; } network_rule: TOK_NETWORK TOK_ID TOK_ID TOK_END_OF_RULE { struct aa_network_entry *entry; entry = network_entry($2, $3, NULL); if (!entry) yyerror(_("Invalid network entry.")); free($2); free($3); $$ = entry; } cond: TOK_CONDID TOK_EQUALS TOK_VALUE { struct cond_entry *ent; struct value_list *value = new_value_list($3); if (!value) yyerror(_("Memory allocation error.")); ent = new_cond_entry($1, 1, value); if (!ent) { free_value_list(value); yyerror(_("Memory allocation error.")); } $$ = ent; } cond: TOK_CONDID TOK_EQUALS TOK_OPENPAREN valuelist TOK_CLOSEPAREN { struct cond_entry *ent = new_cond_entry($1, 1, $4); if (!ent) yyerror(_("Memory allocation error.")); $$ = ent; } cond: TOK_CONDID TOK_IN TOK_OPENPAREN valuelist TOK_CLOSEPAREN { struct cond_entry *ent = new_cond_entry($1, 0, $4); if (!ent) yyerror(_("Memory allocation error.")); $$ = ent; } opt_conds: { /* nothing */ $$ = NULL; } | opt_conds cond { $2->next = $1; $$ = $2; } cond_list: TOK_CONDLISTID TOK_EQUALS TOK_OPENPAREN opt_conds TOK_CLOSEPAREN { $$.name = $1; $$.list = $4; } opt_cond_list: { /* nothing */ $$ = { NULL, NULL }; } | cond_list { $$ = $1; } mnt_rule: TOK_MOUNT opt_conds opt_id TOK_END_OF_RULE { $$ = do_mnt_rule($2, $3, NULL, NULL, AA_MAY_MOUNT); } mnt_rule: TOK_MOUNT opt_conds opt_id TOK_ARROW opt_conds TOK_ID TOK_END_OF_RULE { $$ = do_mnt_rule($2, $3, $5, $6, AA_MAY_MOUNT); } mnt_rule: TOK_REMOUNT opt_conds opt_id TOK_END_OF_RULE { $$ = do_mnt_rule($2, NULL, NULL, $3, AA_DUMMY_REMOUNT); } mnt_rule: TOK_UMOUNT opt_conds opt_id TOK_END_OF_RULE { $$ = do_mnt_rule($2, NULL, NULL, $3, AA_MAY_UMOUNT); } mnt_rule: TOK_PIVOTROOT opt_conds opt_id opt_target TOK_END_OF_RULE { $$ = do_pivot_rule($2, $3, $4); } dbus_perm: TOK_VALUE { if (strcmp($1, "bind") == 0) $$ = AA_DBUS_BIND; else if (strcmp($1, "send") == 0 || strcmp($1, "write") == 0) $$ = AA_DBUS_SEND; else if (strcmp($1, "receive") == 0 || strcmp($1, "read") == 0) $$ = AA_DBUS_RECEIVE; else if (strcmp($1, "eavesdrop") == 0) $$ = AA_DBUS_EAVESDROP; else if ($1) { parse_dbus_mode($1, &$$, 1); } else $$ = 0; if ($1) free($1); } | TOK_BIND { $$ = AA_DBUS_BIND; } | TOK_SEND { $$ = AA_DBUS_SEND; } | TOK_RECEIVE { $$ = AA_DBUS_RECEIVE; } | TOK_READ { $$ = AA_DBUS_RECEIVE; } | TOK_WRITE { $$ = AA_DBUS_SEND; } | TOK_EAVESDROP { $$ = AA_DBUS_EAVESDROP; } | TOK_MODE { parse_dbus_mode($1, &$$, 1); free($1); } dbus_perms: { /* nothing */ $$ = 0; } | dbus_perms dbus_perm { $$ = $1 | $2; } | dbus_perms TOK_COMMA dbus_perm { $$ = $1 | $3; } opt_dbus_perm: { /* nothing */ $$ = 0; } | dbus_perm { $$ = $1; } | TOK_OPENPAREN dbus_perms TOK_CLOSEPAREN { $$ = $2; } dbus_rule: TOK_DBUS opt_dbus_perm opt_conds opt_cond_list TOK_END_OF_RULE { dbus_rule *ent; if ($4.name) { if (strcmp($4.name, "peer") != 0) yyerror(_("dbus rule: invalid conditional group %s=()"), $4.name); free($4.name); } ent = new dbus_rule($2, $3, $4.list); if (!ent) { yyerror(_("Memory allocation error.")); } $$ = ent; } net_perm: TOK_VALUE { if (strcmp($1, "create") == 0) $$ = AA_NET_CREATE; else if (strcmp($1, "bind") == 0) $$ = AA_NET_BIND; else if (strcmp($1, "listen") == 0) $$ = AA_NET_LISTEN; else if (strcmp($1, "accept") == 0) $$ = AA_NET_ACCEPT; else if (strcmp($1, "connect") == 0) $$ = AA_NET_CONNECT; else if (strcmp($1, "shutdown") == 0) $$ = AA_NET_SHUTDOWN; else if (strcmp($1, "getattr") == 0) $$ = AA_NET_GETATTR; else if (strcmp($1, "setattr") == 0) $$ = AA_NET_SETATTR; else if (strcmp($1, "getopt") == 0) $$ = AA_NET_GETOPT; else if (strcmp($1, "setopt") == 0) $$ = AA_NET_SETOPT; else if (strcmp($1, "send") == 0 || strcmp($1, "write") == 0) $$ = AA_NET_SEND; else if (strcmp($1, "receive") == 0 || strcmp($1, "read") == 0) $$ = AA_NET_RECEIVE; else if ($1) { parse_net_mode($1, &$$, 1); } else $$ = 0; if ($1) free($1); } | TOK_CREATE { $$ = AA_NET_CREATE; } | TOK_BIND { $$ = AA_NET_BIND; } | TOK_LISTEN { $$ = AA_NET_LISTEN; } | TOK_ACCEPT { $$ = AA_NET_ACCEPT; } | TOK_CONNECT { $$ = AA_NET_CONNECT; } | TOK_SHUTDOWN { $$ = AA_NET_SHUTDOWN; } | TOK_GETATTR { $$ = AA_NET_GETATTR; } | TOK_SETATTR { $$ = AA_NET_SETATTR; } | TOK_GETOPT { $$ = AA_NET_GETOPT; } | TOK_SETOPT { $$ = AA_NET_SETOPT; } | TOK_SEND { $$ = AA_NET_SEND; } | TOK_RECEIVE { $$ = AA_NET_RECEIVE; } | TOK_READ { $$ = AA_NET_RECEIVE; } | TOK_WRITE { $$ = AA_NET_SEND; } | TOK_MODE { parse_unix_mode($1, &$$, 1); free($1); } net_perms: { /* nothing */ $$ = 0; } | net_perms net_perm { $$ = $1 | $2; } | net_perms TOK_COMMA net_perm { $$ = $1 | $3; } opt_net_perm: { /* nothing */ $$ = 0; } | net_perm { $$ = $1; } | TOK_OPENPAREN net_perms TOK_CLOSEPAREN { $$ = $2; } unix_rule: TOK_UNIX opt_net_perm opt_conds opt_cond_list TOK_END_OF_RULE { unix_rule *ent; if ($4.name) { if (strcmp($4.name, "peer") != 0) yyerror(_("unix rule: invalid conditional group %s=()"), $4.name); free($4.name); } ent = new unix_rule($2, $3, $4.list); if (!ent) { yyerror(_("Memory allocation error.")); } $$ = ent; } signal_perm: TOK_VALUE { if (strcmp($1, "send") == 0 || strcmp($1, "write") == 0) $$ = AA_MAY_SEND; else if (strcmp($1, "receive") == 0 || strcmp($1, "read") == 0) $$ = AA_MAY_RECEIVE; else if ($1) { parse_signal_mode($1, &$$, 1); } else $$ = 0; if ($1) free($1); } | TOK_SEND { $$ = AA_MAY_SEND; } | TOK_RECEIVE { $$ = AA_MAY_RECEIVE; } | TOK_READ { $$ = AA_MAY_RECEIVE; } | TOK_WRITE { $$ = AA_MAY_SEND; } | TOK_MODE { parse_signal_mode($1, &$$, 1); free($1); } signal_perms: { /* nothing */ $$ = 0; } | signal_perms signal_perm { $$ = $1 | $2; } | signal_perms TOK_COMMA signal_perm { $$ = $1 | $3; } opt_signal_perm: { /* nothing */ $$ = 0; } | signal_perm { $$ = $1; } | TOK_OPENPAREN signal_perms TOK_CLOSEPAREN { $$ = $2; } signal_rule: TOK_SIGNAL opt_signal_perm opt_conds TOK_END_OF_RULE { signal_rule *ent = new signal_rule($2, $3); $$ = ent; } ptrace_perm: TOK_VALUE { if (strcmp($1, "trace") == 0 || strcmp($1, "write") == 0) $$ = AA_MAY_TRACE; else if (strcmp($1, "read") == 0) $$ = AA_MAY_READ; else if (strcmp($1, "tracedby") == 0) $$ = AA_MAY_TRACEDBY; else if (strcmp($1, "readby") == 0) $$ = AA_MAY_READBY; else if ($1) parse_ptrace_mode($1, &$$, 1); else $$ = 0; if ($1) free($1); } | TOK_TRACE { $$ = AA_MAY_TRACE; } | TOK_TRACEDBY { $$ = AA_MAY_TRACEDBY; } | TOK_READ { $$ = AA_MAY_READ; } | TOK_WRITE { $$ = AA_MAY_TRACE; } | TOK_READBY { $$ = AA_MAY_READBY; } | TOK_MODE { parse_ptrace_mode($1, &$$, 1); free($1); } ptrace_perms: { /* nothing */ $$ = 0; } | ptrace_perms ptrace_perm { $$ = $1 | $2; } | ptrace_perms TOK_COMMA ptrace_perm { $$ = $1 | $3; } opt_ptrace_perm: { /* nothing */ $$ = 0; } | ptrace_perm { $$ = $1; } | TOK_OPENPAREN ptrace_perms TOK_CLOSEPAREN { $$ = $2; } ptrace_rule: TOK_PTRACE opt_ptrace_perm opt_conds TOK_END_OF_RULE { ptrace_rule *ent = new ptrace_rule($2, $3); $$ = ent; } hat_start: TOK_CARET {} | TOK_HAT {} file_mode: TOK_MODE { /* A single TOK_MODE maps to the same permission in all * of user::other */ $$ = parse_mode($1); free($1); } change_profile: TOK_CHANGE_PROFILE opt_exec_mode opt_id opt_named_transition TOK_END_OF_RULE { struct cod_entry *entry; int mode = AA_CHANGE_PROFILE; int exec_mode = $2; char *exec = $3; char *target = $4; if (exec) { /* exec bits required to trigger rule conflict if * for overlapping safe and unsafe exec rules */ mode |= AA_EXEC_BITS; if (exec_mode == EXEC_MODE_UNSAFE) mode |= ALL_AA_EXEC_UNSAFE; else if (exec_mode == EXEC_MODE_SAFE && !kernel_supports_stacking && warnflags & WARN_RULE_DOWNGRADED) { pwarn("downgrading change_profile safe rule to unsafe due to lack of necessary kernel support\n"); /** * No need to do anything because 'unsafe' exec * mode is the only supported mode of * change_profile rules in non-stacking kernels */ } } else if (exec_mode != EXEC_MODE_EMPTY) yyerror(_("Exec condition is required when unsafe or safe keywords are present")); if (exec && !(exec[0] == '/' || strncmp(exec, "@{", 2) == 0)) yyerror(_("Exec condition must begin with '/'.")); if (target) { PDEBUG("Matched change_profile: tok_id (%s)\n", target); } else { PDEBUG("Matched change_profile,\n"); target = strdup("**"); if (!target) yyerror(_("Memory allocation error.")); } entry = new_entry(target, mode, exec); if (!entry) yyerror(_("Memory allocation error.")); PDEBUG("change_profile.entry: (%s)\n", entry->name); $$ = entry; }; capability: TOK_CAPABILITY caps TOK_END_OF_RULE { if ($2 == 0) { /* bare capability keyword - set all caps */ $$ = 0xffffffffffffffff; } else $$ = $2; }; caps: { /* nothing */ $$ = 0; } | caps TOK_ID { int cap = name_to_capability($2); if (cap == -1) yyerror(_("Invalid capability %s."), $2); free($2); $$ = $1 | CAP_TO_MASK(cap); } %% #define MAXBUFSIZE 4096 void vprintyyerror(const char *msg, va_list argptr) { char buf[MAXBUFSIZE]; vsnprintf(buf, sizeof(buf), msg, argptr); if (profilename) { PERROR(_("AppArmor parser error for %s%s%s at line %d: %s\n"), profilename, current_filename ? " in " : "", current_filename ? current_filename : "", current_lineno, buf); } else { PERROR(_("AppArmor parser error,%s%s line %d: %s\n"), current_filename ? " in " : "", current_filename ? current_filename : "", current_lineno, buf); } } void printyyerror(const char *msg, ...) { va_list arg; va_start(arg, msg); vprintyyerror(msg, arg); va_end(arg); } void yyerror(const char *msg, ...) { va_list arg; va_start(arg, msg); vprintyyerror(msg, arg); va_end(arg); exit(1); } struct cod_entry *do_file_rule(char *id, int mode, char *link_id, char *nt) { struct cod_entry *entry; PDEBUG("Matched: tok_id (%s) tok_mode (0x%x)\n", id, mode); entry = new_entry(id, mode, link_id); if (!entry) yyerror(_("Memory allocation error.")); entry->nt_name = nt; PDEBUG("rule.entry: (%s)\n", entry->name); return entry; } /* Note: NOT currently in use, used for * /foo x -> { /bah, } style transitions */ void add_local_entry(Profile *prof) { /* ugh this has to be called after the hat is attached to its parent */ if (prof->local_mode) { struct cod_entry *entry; char *trans = (char *) malloc(strlen(prof->parent->name) + strlen(prof->name) + 3); char *name = strdup(prof->name); if (!trans) yyerror(_("Memory allocation error.")); sprintf(name, "%s//%s", prof->parent->name, prof->name); entry = new_entry(name, prof->local_mode, NULL); entry->audit = prof->local_audit; entry->nt_name = trans; if (!entry) yyerror(_("Memory allocation error.")); add_entry_to_policy(prof, entry); } } static const char *mnt_cond_msg[] = {"", " not allowed as source conditional", " not allowed as target conditional", "", NULL}; int verify_mnt_conds(struct cond_entry *conds, int src) { struct cond_entry *entry; int error = 0; if (!conds) return 0; list_for_each(conds, entry) { int res = is_valid_mnt_cond(entry->name, src); if (res <= 0) { printyyerror(_("invalid mount conditional %s%s"), entry->name, res == -1 ? "" : mnt_cond_msg[src]); error++; } } return error; } mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src, struct cond_entry *dst_conds, char *dst, int mode) { if (verify_mnt_conds(src_conds, MNT_SRC_OPT) != 0) yyerror(_("bad mount rule")); /* FIXME: atm conditions are not supported on dst if (verify_conds(dst_conds, DST_OPT) != 0) yyerror(_("bad mount rule")); */ if (dst_conds) yyerror(_("mount point conditions not currently supported")); mnt_rule *ent = new mnt_rule(src_conds, src, dst_conds, dst, mode); if (!ent) { yyerror(_("Memory allocation error.")); } return ent; } mnt_rule *do_pivot_rule(struct cond_entry *old, char *root, char *transition) { char *device = NULL; if (old) { if (strcmp(old->name, "oldroot") != 0) yyerror(_("invalid pivotroot conditional '%s'"), old->name); if (old->vals) { device = old->vals->value; old->vals->value = NULL; } free_cond_entry(old); } mnt_rule *ent = new mnt_rule(NULL, device, NULL, root, AA_MAY_PIVOTROOT); ent->trans = transition; return ent; } apparmor-2.13.3/parser/COPYING.GPL0000644000175000017500000004337213502024172014166 0ustar jjjjThis license applies to all source files within the AppArmor parser package. GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. apparmor-2.13.3/parser/techdoc.log0000644000175000017500000006205113502024374014625 0ustar jjjjThis is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017/Debian) (preloaded format=pdflatex 2018.10.12) 17 JUN 2019 16:57 entering extended mode restricted \write18 enabled. %&-line parsing enabled. **\def\fixedpdfdate{20190617235538+0000}\input techdoc.tex (./techdoc.tex (/usr/share/texlive/texmf-dist/tex/latex/base/article.cls Document Class: article 2014/09/29 v1.4h Standard LaTeX document class (/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo File: size10.clo 2014/09/29 v1.4h Standard LaTeX file (size option) ) \c@part=\count79 \c@section=\count80 \c@subsection=\count81 \c@subsubsection=\count82 \c@paragraph=\count83 \c@subparagraph=\count84 \c@figure=\count85 \c@table=\count86 \abovecaptionskip=\skip41 \belowcaptionskip=\skip42 \bibindent=\dimen102 ) (/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty Package: inputenc 2015/03/17 v1.2c Input encoding file \inpenc@prehook=\toks14 \inpenc@posthook=\toks15 (/usr/share/texlive/texmf-dist/tex/latex/base/utf8.def File: utf8.def 2017/01/28 v1.1t UTF-8 support for inputenc Now handling font encoding OML ... ... no UTF-8 mapping file for font encoding OML Now handling font encoding T1 ... ... processing UTF-8 mapping file for font encoding T1 (/usr/share/texlive/texmf-dist/tex/latex/base/t1enc.dfu File: t1enc.dfu 2017/01/28 v1.1t UTF-8 support for inputenc defining Unicode char U+00A0 (decimal 160) defining Unicode char U+00A1 (decimal 161) defining Unicode char U+00A3 (decimal 163) defining Unicode char U+00AB (decimal 171) defining Unicode char U+00AD (decimal 173) defining Unicode char U+00BB (decimal 187) defining Unicode char U+00BF (decimal 191) defining Unicode char U+00C0 (decimal 192) defining Unicode char U+00C1 (decimal 193) defining Unicode char U+00C2 (decimal 194) defining Unicode char U+00C3 (decimal 195) defining Unicode char U+00C4 (decimal 196) defining Unicode char U+00C5 (decimal 197) defining Unicode char U+00C6 (decimal 198) defining Unicode char U+00C7 (decimal 199) defining Unicode char U+00C8 (decimal 200) defining Unicode char U+00C9 (decimal 201) defining Unicode char U+00CA (decimal 202) defining Unicode char U+00CB (decimal 203) defining Unicode char U+00CC (decimal 204) defining Unicode char U+00CD (decimal 205) defining Unicode char U+00CE (decimal 206) defining Unicode char U+00CF (decimal 207) defining Unicode char U+00D0 (decimal 208) defining Unicode char U+00D1 (decimal 209) defining Unicode char U+00D2 (decimal 210) defining Unicode char U+00D3 (decimal 211) defining Unicode char U+00D4 (decimal 212) defining Unicode char U+00D5 (decimal 213) defining Unicode char U+00D6 (decimal 214) defining Unicode char U+00D8 (decimal 216) defining Unicode char U+00D9 (decimal 217) defining Unicode char U+00DA (decimal 218) defining Unicode char U+00DB (decimal 219) defining Unicode char U+00DC (decimal 220) defining Unicode char U+00DD (decimal 221) defining Unicode char U+00DE (decimal 222) defining Unicode char U+00DF (decimal 223) defining Unicode char U+00E0 (decimal 224) defining Unicode char U+00E1 (decimal 225) defining Unicode char U+00E2 (decimal 226) defining Unicode char U+00E3 (decimal 227) defining Unicode char U+00E4 (decimal 228) defining Unicode char U+00E5 (decimal 229) defining Unicode char U+00E6 (decimal 230) defining Unicode char U+00E7 (decimal 231) defining Unicode char U+00E8 (decimal 232) defining Unicode char U+00E9 (decimal 233) defining Unicode char U+00EA (decimal 234) defining Unicode char U+00EB (decimal 235) defining Unicode char U+00EC (decimal 236) defining Unicode char U+00ED (decimal 237) defining Unicode char U+00EE (decimal 238) defining Unicode char U+00EF (decimal 239) defining Unicode char U+00F0 (decimal 240) defining Unicode char U+00F1 (decimal 241) defining Unicode char U+00F2 (decimal 242) defining Unicode char U+00F3 (decimal 243) defining Unicode char U+00F4 (decimal 244) defining Unicode char U+00F5 (decimal 245) defining Unicode char U+00F6 (decimal 246) defining Unicode char U+00F8 (decimal 248) defining Unicode char U+00F9 (decimal 249) defining Unicode char U+00FA (decimal 250) defining Unicode char U+00FB (decimal 251) defining Unicode char U+00FC (decimal 252) defining Unicode char U+00FD (decimal 253) defining Unicode char U+00FE (decimal 254) defining Unicode char U+00FF (decimal 255) defining Unicode char U+0100 (decimal 256) defining Unicode char U+0101 (decimal 257) defining Unicode char U+0102 (decimal 258) defining Unicode char U+0103 (decimal 259) defining Unicode char U+0104 (decimal 260) defining Unicode char U+0105 (decimal 261) defining Unicode char U+0106 (decimal 262) defining Unicode char U+0107 (decimal 263) defining Unicode char U+0108 (decimal 264) defining Unicode char U+0109 (decimal 265) defining Unicode char U+010A (decimal 266) defining Unicode char U+010B (decimal 267) defining Unicode char U+010C (decimal 268) defining Unicode char U+010D (decimal 269) defining Unicode char U+010E (decimal 270) defining Unicode char U+010F (decimal 271) defining Unicode char U+0110 (decimal 272) defining Unicode char U+0111 (decimal 273) defining Unicode char U+0112 (decimal 274) defining Unicode char U+0113 (decimal 275) defining Unicode char U+0114 (decimal 276) defining Unicode char U+0115 (decimal 277) defining Unicode char U+0116 (decimal 278) defining Unicode char U+0117 (decimal 279) defining Unicode char U+0118 (decimal 280) defining Unicode char U+0119 (decimal 281) defining Unicode char U+011A (decimal 282) defining Unicode char U+011B (decimal 283) defining Unicode char U+011C (decimal 284) defining Unicode char U+011D (decimal 285) defining Unicode char U+011E (decimal 286) defining Unicode char U+011F (decimal 287) defining Unicode char U+0120 (decimal 288) defining Unicode char U+0121 (decimal 289) defining Unicode char U+0122 (decimal 290) defining Unicode char U+0123 (decimal 291) defining Unicode char U+0124 (decimal 292) defining Unicode char U+0125 (decimal 293) defining Unicode char U+0128 (decimal 296) defining Unicode char U+0129 (decimal 297) defining Unicode char U+012A (decimal 298) defining Unicode char U+012B (decimal 299) defining Unicode char U+012C (decimal 300) defining Unicode char U+012D (decimal 301) defining Unicode char U+012E (decimal 302) defining Unicode char U+012F (decimal 303) defining Unicode char U+0130 (decimal 304) defining Unicode char U+0131 (decimal 305) defining Unicode char U+0132 (decimal 306) defining Unicode char U+0133 (decimal 307) defining Unicode char U+0134 (decimal 308) defining Unicode char U+0135 (decimal 309) defining Unicode char U+0136 (decimal 310) defining Unicode char U+0137 (decimal 311) defining Unicode char U+0139 (decimal 313) defining Unicode char U+013A (decimal 314) defining Unicode char U+013B (decimal 315) defining Unicode char U+013C (decimal 316) defining Unicode char U+013D (decimal 317) defining Unicode char U+013E (decimal 318) defining Unicode char U+0141 (decimal 321) defining Unicode char U+0142 (decimal 322) defining Unicode char U+0143 (decimal 323) defining Unicode char U+0144 (decimal 324) defining Unicode char U+0145 (decimal 325) defining Unicode char U+0146 (decimal 326) defining Unicode char U+0147 (decimal 327) defining Unicode char U+0148 (decimal 328) defining Unicode char U+014A (decimal 330) defining Unicode char U+014B (decimal 331) defining Unicode char U+014C (decimal 332) defining Unicode char U+014D (decimal 333) defining Unicode char U+014E (decimal 334) defining Unicode char U+014F (decimal 335) defining Unicode char U+0150 (decimal 336) defining Unicode char U+0151 (decimal 337) defining Unicode char U+0152 (decimal 338) defining Unicode char U+0153 (decimal 339) defining Unicode char U+0154 (decimal 340) defining Unicode char U+0155 (decimal 341) defining Unicode char U+0156 (decimal 342) defining Unicode char U+0157 (decimal 343) defining Unicode char U+0158 (decimal 344) defining Unicode char U+0159 (decimal 345) defining Unicode char U+015A (decimal 346) defining Unicode char U+015B (decimal 347) defining Unicode char U+015C (decimal 348) defining Unicode char U+015D (decimal 349) defining Unicode char U+015E (decimal 350) defining Unicode char U+015F (decimal 351) defining Unicode char U+0160 (decimal 352) defining Unicode char U+0161 (decimal 353) defining Unicode char U+0162 (decimal 354) defining Unicode char U+0163 (decimal 355) defining Unicode char U+0164 (decimal 356) defining Unicode char U+0165 (decimal 357) defining Unicode char U+0168 (decimal 360) defining Unicode char U+0169 (decimal 361) defining Unicode char U+016A (decimal 362) defining Unicode char U+016B (decimal 363) defining Unicode char U+016C (decimal 364) defining Unicode char U+016D (decimal 365) defining Unicode char U+016E (decimal 366) defining Unicode char U+016F (decimal 367) defining Unicode char U+0170 (decimal 368) defining Unicode char U+0171 (decimal 369) defining Unicode char U+0172 (decimal 370) defining Unicode char U+0173 (decimal 371) defining Unicode char U+0174 (decimal 372) defining Unicode char U+0175 (decimal 373) defining Unicode char U+0176 (decimal 374) defining Unicode char U+0177 (decimal 375) defining Unicode char U+0178 (decimal 376) defining Unicode char U+0179 (decimal 377) defining Unicode char U+017A (decimal 378) defining Unicode char U+017B (decimal 379) defining Unicode char U+017C (decimal 380) defining Unicode char U+017D (decimal 381) defining Unicode char U+017E (decimal 382) defining Unicode char U+01CD (decimal 461) defining Unicode char U+01CE (decimal 462) defining Unicode char U+01CF (decimal 463) defining Unicode char U+01D0 (decimal 464) defining Unicode char U+01D1 (decimal 465) defining Unicode char U+01D2 (decimal 466) defining Unicode char U+01D3 (decimal 467) defining Unicode char U+01D4 (decimal 468) defining Unicode char U+01E2 (decimal 482) defining Unicode char U+01E3 (decimal 483) defining Unicode char U+01E6 (decimal 486) defining Unicode char U+01E7 (decimal 487) defining Unicode char U+01E8 (decimal 488) defining Unicode char U+01E9 (decimal 489) defining Unicode char U+01EA (decimal 490) defining Unicode char U+01EB (decimal 491) defining Unicode char U+01F0 (decimal 496) defining Unicode char U+01F4 (decimal 500) defining Unicode char U+01F5 (decimal 501) defining Unicode char U+0218 (decimal 536) defining Unicode char U+0219 (decimal 537) defining Unicode char U+021A (decimal 538) defining Unicode char U+021B (decimal 539) defining Unicode char U+0232 (decimal 562) defining Unicode char U+0233 (decimal 563) defining Unicode char U+1E02 (decimal 7682) defining Unicode char U+1E03 (decimal 7683) defining Unicode char U+200C (decimal 8204) defining Unicode char U+2010 (decimal 8208) defining Unicode char U+2011 (decimal 8209) defining Unicode char U+2012 (decimal 8210) defining Unicode char U+2013 (decimal 8211) defining Unicode char U+2014 (decimal 8212) defining Unicode char U+2015 (decimal 8213) defining Unicode char U+2018 (decimal 8216) defining Unicode char U+2019 (decimal 8217) defining Unicode char U+201A (decimal 8218) defining Unicode char U+201C (decimal 8220) defining Unicode char U+201D (decimal 8221) defining Unicode char U+201E (decimal 8222) defining Unicode char U+2030 (decimal 8240) defining Unicode char U+2031 (decimal 8241) defining Unicode char U+2039 (decimal 8249) defining Unicode char U+203A (decimal 8250) defining Unicode char U+2423 (decimal 9251) defining Unicode char U+1E20 (decimal 7712) defining Unicode char U+1E21 (decimal 7713) ) Now handling font encoding OT1 ... ... processing UTF-8 mapping file for font encoding OT1 (/usr/share/texlive/texmf-dist/tex/latex/base/ot1enc.dfu File: ot1enc.dfu 2017/01/28 v1.1t UTF-8 support for inputenc defining Unicode char U+00A0 (decimal 160) defining Unicode char U+00A1 (decimal 161) defining Unicode char U+00A3 (decimal 163) defining Unicode char U+00AD (decimal 173) defining Unicode char U+00B8 (decimal 184) defining Unicode char U+00BF (decimal 191) defining Unicode char U+00C5 (decimal 197) defining Unicode char U+00C6 (decimal 198) defining Unicode char U+00D8 (decimal 216) defining Unicode char U+00DF (decimal 223) defining Unicode char U+00E6 (decimal 230) defining Unicode char U+00EC (decimal 236) defining Unicode char U+00ED (decimal 237) defining Unicode char U+00EE (decimal 238) defining Unicode char U+00EF (decimal 239) defining Unicode char U+00F8 (decimal 248) defining Unicode char U+0131 (decimal 305) defining Unicode char U+0141 (decimal 321) defining Unicode char U+0142 (decimal 322) defining Unicode char U+0152 (decimal 338) defining Unicode char U+0153 (decimal 339) defining Unicode char U+0174 (decimal 372) defining Unicode char U+0175 (decimal 373) defining Unicode char U+0176 (decimal 374) defining Unicode char U+0177 (decimal 375) defining Unicode char U+0218 (decimal 536) defining Unicode char U+0219 (decimal 537) defining Unicode char U+021A (decimal 538) defining Unicode char U+021B (decimal 539) defining Unicode char U+2013 (decimal 8211) defining Unicode char U+2014 (decimal 8212) defining Unicode char U+2018 (decimal 8216) defining Unicode char U+2019 (decimal 8217) defining Unicode char U+201C (decimal 8220) defining Unicode char U+201D (decimal 8221) ) Now handling font encoding OMS ... ... processing UTF-8 mapping file for font encoding OMS (/usr/share/texlive/texmf-dist/tex/latex/base/omsenc.dfu File: omsenc.dfu 2017/01/28 v1.1t UTF-8 support for inputenc defining Unicode char U+00A7 (decimal 167) defining Unicode char U+00B6 (decimal 182) defining Unicode char U+00B7 (decimal 183) defining Unicode char U+2020 (decimal 8224) defining Unicode char U+2021 (decimal 8225) defining Unicode char U+2022 (decimal 8226) ) Now handling font encoding OMX ... ... no UTF-8 mapping file for font encoding OMX Now handling font encoding U ... ... no UTF-8 mapping file for font encoding U defining Unicode char U+00A9 (decimal 169) defining Unicode char U+00AA (decimal 170) defining Unicode char U+00AE (decimal 174) defining Unicode char U+00BA (decimal 186) defining Unicode char U+02C6 (decimal 710) defining Unicode char U+02DC (decimal 732) defining Unicode char U+200C (decimal 8204) defining Unicode char U+2026 (decimal 8230) defining Unicode char U+2122 (decimal 8482) defining Unicode char U+2423 (decimal 9251) )) (/usr/share/texlive/texmf-dist/tex/latex/url/url.sty \Urlmuskip=\muskip10 Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. ) (/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty Package: hyperref 2018/02/06 v6.86b Hypertext links for LaTeX (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty Package: hobsub-hyperref 2016/05/16 v1.14 Bundle oberdiek, subset hyperref (HO) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty Package: hobsub-generic 2016/05/16 v1.14 Bundle oberdiek, subset generic (HO) Package: hobsub 2016/05/16 v1.14 Construct package bundles (HO) Package: infwarerr 2016/05/16 v1.4 Providing info/warning/error messages (HO) Package: ltxcmds 2016/05/16 v1.23 LaTeX kernel commands for general use (HO) Package: ifluatex 2016/05/16 v1.4 Provides the ifluatex switch (HO) Package ifluatex Info: LuaTeX not detected. Package: ifvtex 2016/05/16 v1.6 Detect VTeX and its facilities (HO) Package ifvtex Info: VTeX not detected. Package: intcalc 2016/05/16 v1.2 Expandable calculations with integers (HO) Package: ifpdf 2017/03/15 v3.2 Provides the ifpdf switch Package: etexcmds 2016/05/16 v1.6 Avoid name clashes with e-TeX commands (HO) Package etexcmds Info: Could not find \expanded. (etexcmds) That can mean that you are not using pdfTeX 1.50 or (etexcmds) that some package has redefined \expanded. (etexcmds) In the latter case, load this package earlier. Package: kvsetkeys 2016/05/16 v1.17 Key value parser (HO) Package: kvdefinekeys 2016/05/16 v1.4 Define keys (HO) Package: pdftexcmds 2018/01/21 v0.26 Utility functions of pdfTeX for LuaTeX (HO ) Package pdftexcmds Info: LuaTeX not detected. Package pdftexcmds Info: \pdf@primitive is available. Package pdftexcmds Info: \pdf@ifprimitive is available. Package pdftexcmds Info: \pdfdraftmode found. Package: pdfescape 2016/05/16 v1.14 Implements pdfTeX's escape features (HO) Package: bigintcalc 2016/05/16 v1.4 Expandable calculations on big integers (HO ) Package: bitset 2016/05/16 v1.2 Handle bit-vector datatype (HO) Package: uniquecounter 2016/05/16 v1.3 Provide unlimited unique counter (HO) ) Package hobsub Info: Skipping package `hobsub' (already loaded). Package: letltxmacro 2016/05/16 v1.5 Let assignment for LaTeX macros (HO) Package: hopatch 2016/05/16 v1.3 Wrapper for package hooks (HO) Package: xcolor-patch 2016/05/16 xcolor patch Package: atveryend 2016/05/16 v1.9 Hooks at the very end of document (HO) Package atveryend Info: \enddocument detected (standard20110627). Package: atbegshi 2016/06/09 v1.18 At begin shipout hook (HO) Package: refcount 2016/05/16 v3.5 Data extraction from label references (HO) Package: hycolor 2016/05/16 v1.8 Color options for hyperref/bookmark (HO) ) (/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty Package: keyval 2014/10/28 v1.15 key=value parser (DPC) \KV@toks@=\toks16 ) (/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional ) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/auxhook.sty Package: auxhook 2016/05/16 v1.4 Hooks for auxiliary files (HO) ) (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty Package: kvoptions 2016/05/16 v3.12 Key value format for package options (HO) ) \@linkdim=\dimen103 \Hy@linkcounter=\count87 \Hy@pagecounter=\count88 (/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def File: pd1enc.def 2018/02/06 v6.86b Hyperref: PDFDocEncoding definition (HO) Now handling font encoding PD1 ... ... no UTF-8 mapping file for font encoding PD1 ) \Hy@SavedSpaceFactor=\count89 (/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive ) Package hyperref Info: Hyper figures OFF on input line 4509. Package hyperref Info: Link nesting OFF on input line 4514. Package hyperref Info: Hyper index ON on input line 4517. Package hyperref Info: Plain pages OFF on input line 4524. Package hyperref Info: Backreferencing OFF on input line 4529. Package hyperref Info: Implicit mode ON; LaTeX internals redefined. Package hyperref Info: Bookmarks ON on input line 4762. \c@Hy@tempcnt=\count90 LaTeX Info: Redefining \url on input line 5115. \XeTeXLinkMargin=\dimen104 \Fld@menulength=\count91 \Field@Width=\dimen105 \Fld@charsize=\dimen106 Package hyperref Info: Hyper figures OFF on input line 6369. Package hyperref Info: Link nesting OFF on input line 6374. Package hyperref Info: Hyper index ON on input line 6377. Package hyperref Info: backreferencing OFF on input line 6384. Package hyperref Info: Link coloring OFF on input line 6389. Package hyperref Info: Link coloring with OCG OFF on input line 6394. Package hyperref Info: PDF/A mode OFF on input line 6399. LaTeX Info: Redefining \ref on input line 6439. LaTeX Info: Redefining \pageref on input line 6443. \Hy@abspage=\count92 \c@Item=\count93 \c@Hfootnote=\count94 ) Package hyperref Info: Driver: hpdftex. (/usr/share/texlive/texmf-dist/tex/latex/hyperref/hpdftex.def File: hpdftex.def 2018/02/06 v6.86b Hyperref driver for pdfTeX \Fld@listcount=\count95 \c@bookmark@seq@number=\count96 (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty Package: rerunfilecheck 2016/05/16 v1.8 Rerun checks for auxiliary files (HO) Package uniquecounter Info: New unique counter `rerunfilecheck' on input line 2 82. ) \Hy@SectionHShift=\skip43 ) (./techdoc.aux) \openout1 = `techdoc.aux'. LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 31. LaTeX Font Info: ... okay on input line 31. LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 31. LaTeX Font Info: ... okay on input line 31. LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 31. LaTeX Font Info: ... okay on input line 31. LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 31. LaTeX Font Info: ... okay on input line 31. LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 31. LaTeX Font Info: ... okay on input line 31. LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 31. LaTeX Font Info: ... okay on input line 31. LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 31. LaTeX Font Info: ... okay on input line 31. \AtBeginShipoutBox=\box26 Package hyperref Info: Link coloring OFF on input line 31. (/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty Package: nameref 2016/05/21 v2.44 Cross-referencing by name of section (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty Package: gettitlestring 2016/05/16 v1.5 Cleanup title references (HO) ) \c@section@level=\count97 ) LaTeX Info: Redefining \ref on input line 31. LaTeX Info: Redefining \pageref on input line 31. LaTeX Info: Redefining \nameref on input line 31. (./techdoc.out) (./techdoc.out) \@outlinefile=\write3 \openout3 = `techdoc.out'. LaTeX Font Info: External font `cmex10' loaded for size (Font) <12> on input line 34. LaTeX Font Info: External font `cmex10' loaded for size (Font) <8> on input line 34. LaTeX Font Info: External font `cmex10' loaded for size (Font) <6> on input line 34. (./techdoc.toc LaTeX Font Info: External font `cmex10' loaded for size (Font) <7> on input line 4. LaTeX Font Info: External font `cmex10' loaded for size (Font) <5> on input line 4. ) \tf@toc=\write4 \openout4 = `techdoc.toc'. [1 {/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] [2] [3] [4] [5] [6] [7] [8 ] [9] [10] [11] [12] [13] LaTeX Font Info: Try loading font information for OMS+cmr on input line 889. (/usr/share/texlive/texmf-dist/tex/latex/base/omscmr.fd File: omscmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions ) LaTeX Font Info: Font shape `OMS/cmr/m/n' in size <10> not available (Font) Font shape `OMS/cmsy/m/n' tried instead on input line 889. [14] [15] [16] [17] [18] [19] Underfull \hbox (badness 1253) in paragraph at lines 1283--1285 []\OT1/cmr/m/n/10 AppArmor doc-u-men-ta-tion, []$\OT1/cmtt/m/n/10 http : / / ww w . novell . com / documentation / [] Package atveryend Info: Empty hook `BeforeClearDocument' on input line 1302. [20] Package atveryend Info: Empty hook `AfterLastShipout' on input line 1302. (./techdoc.aux) Package atveryend Info: Executing hook `AtVeryEndDocument' on input line 1302. Package atveryend Info: Executing hook `AtEndAfterFileList' on input line 1302. Package rerunfilecheck Info: File `techdoc.out' has not changed. (rerunfilecheck) Checksum: 58F88F585BA9D4AF6AE29A9D5F8D557A;2172. Package atveryend Info: Empty hook `AtVeryVeryEnd' on input line 1302. ) Here is how much of TeX's memory you used: 4686 strings out of 494847 67961 string characters out of 6179079 150399 words of memory out of 5000000 7944 multiletter control sequences out of 15000+600000 9521 words of font info for 35 fonts, out of 8000000 for 9000 61 hyphenation exceptions out of 8191 28i,8n,28p,336b,483s stack positions out of 5000i,500n,10000p,200000b,80000s < /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmtt12.pfb> Output written on techdoc.pdf (20 pages, 235502 bytes). PDF statistics: 360 PDF objects out of 1000 (max. 8388607) 318 compressed objects within 4 object streams 60 named destinations out of 1000 (max. 500000) 241 words of extra memory for PDF output out of 10000 (max. 10000000) apparmor-2.13.3/parser/parser_lex.l0000644000175000017500000004245213502024172015031 0ustar jjjj/* * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 * NOVELL (All rights reserved) * Copyright (c) 2010 - 2013 * Canonical Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Canonical, Ltd. */ /* Definitions section */ /* %option main */ /* eliminates need to link with libfl */ %option noyywrap %option nounput %option stack %{ #include #include #include #include #include #include #include #include #include "parser.h" #include "profile.h" #include "parser_include.h" #include "parser_yacc.h" #include "lib.h" #include "policy_cache.h" #ifdef PDEBUG #undef PDEBUG #endif /* #define DEBUG */ #ifdef DEBUG static int yy_top_state(void); #define PDEBUG(fmt, args...) fprintf(stderr, "Lexer (Line %d) (state %s): " fmt, current_lineno, state_names[YY_START].c_str(), ## args) #else #define PDEBUG(fmt, args...) /* Do nothing */ #endif #define NPDEBUG(fmt, args...) /* Do nothing */ #define DUMP_PREPROCESS do { if (preprocess_only) ECHO; } while (0) #define DUMP_AND_DEBUG(X...) \ do { \ DUMP_PREPROCESS; \ PDEBUG(X); \ } while (0) #define EAT_TOKEN(X...) DUMP_AND_DEBUG(X) #define RETURN_TOKEN(X) \ do { \ DUMP_AND_DEBUG("Matched: '%s' Returning(%s)\n", yytext, #X); \ return (X); \ } while (0) #define POP() \ do { \ DUMP_AND_DEBUG(" (pop_to(%s)): Matched: %s\n", state_names[yy_top_state()].c_str(), yytext); \ yy_pop_state(); \ } while (0) #define POP_NODUMP() \ do { \ PDEBUG(" (pop_to(%s)): Matched: %s\n", state_names[yy_top_state()].c_str(), yytext); \ yy_pop_state(); \ } while (0) #define PUSH(X) \ do { \ DUMP_AND_DEBUG(" (push(%s)): Matched: %s\n", state_names[(X)].c_str(), yytext); \ yy_push_state(X); \ } while (0) #define POP_AND_RETURN(X) \ do { \ POP(); \ return (X); \ } while (0) #define PUSH_AND_RETURN(X, Y) \ do { \ PUSH(X); \ return (Y); \ } while (0) #define BEGIN_AND_RETURN(X, Y) \ do { \ DUMP_AND_DEBUG(" (begin(%s)): Matched: %s\n", state_names[(X)].c_str(), yytext); \ BEGIN(X); \ return (Y); \ } while (0) #define YY_NO_INPUT #define STATE_TABLE_ENT(X) {X, #X } extern unordered_map state_names; struct cb_struct { const char *fullpath; const char *filename; }; static int include_dir_cb(int dirfd unused, const char *name, struct stat *st, void *data) { struct cb_struct *d = (struct cb_struct *) data; autofree char *path = NULL; if (asprintf(&path, "%s/%s", d->fullpath, name) < 0) yyerror("Out of memory"); if (is_blacklisted(name, path)) return 0; if (S_ISREG(st->st_mode)) { if (!(yyin = fopen(path,"r"))) yyerror(_("Could not open '%s' in '%s'"), path, d->filename); PDEBUG("Opened include \"%s\" in \"%s\"\n", path, d->filename); update_mru_tstamp(yyin, path); push_include_stack(path); yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE)); } return 0; } void include_filename(char *filename, int search, bool if_exists) { FILE *include_file = NULL; struct stat my_stat; autofree char *fullpath = NULL; if (search) { if (preprocess_only) fprintf(yyout, "\n\n##included <%s>\n", filename); include_file = search_path(filename, &fullpath); } else { if (preprocess_only) fprintf(yyout, "\n\n##included \"%s\"\n", filename); fullpath = strdup(filename); include_file = fopen(fullpath, "r"); } if (!include_file) { if (if_exists) return; yyerror(_("Could not open '%s'"), fullpath ? fullpath: filename); } if (fstat(fileno(include_file), &my_stat)) yyerror(_("fstat failed for '%s'"), fullpath); if (S_ISREG(my_stat.st_mode)) { yyin = include_file; update_mru_tstamp(include_file, fullpath); PDEBUG("Opened include \"%s\"\n", fullpath); push_include_stack(fullpath); yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE )); } else if (S_ISDIR(my_stat.st_mode)) { struct cb_struct data = { fullpath, filename }; fclose(include_file); include_file = NULL; if (dirat_for_each(AT_FDCWD, fullpath, &data, include_dir_cb)) { yyerror(_("Could not process include directory" " '%s' in '%s'"), fullpath, filename);; } } } %} CARET "^" OPEN_BRACE \{ CLOSE_BRACE \} SLASH \/ COLON : AMPERSAND & END_OF_RULE [,] RANGE - MODE_CHARS ([RrWwaLlMmkXx])|(([Pp]|[Cc])[Xx])|(([Pp]|[Cc])?([IiUu])[Xx]) MODES {MODE_CHARS}+ WS [[:blank:]] NUMBER [[:digit:]]+ ID_CHARS [^ \t\r\n"!,] ID {ID_CHARS}|(,{ID_CHARS}|\\[ ]|\\\t|\\\"|\\!|\\,) IDS {ID}+ POST_VAR_ID_CHARS [^ \t\n"!,]{-}[=\+] POST_VAR_ID {POST_VAR_ID_CHARS}|(,{POST_VAR_ID_CHARS}|\\[ ]|\\\t|\\\"|\\!|\\,|\\\(|\\\)) LIST_VALUE_ID_CHARS ([^ \t\n"!,]{-}[()]|\\[ ]|\\\t|\\\"|\\!|\\,|\\\(|\\\)) LIST_VALUE_QUOTED_ID_CHARS [^\0"]|\\\" LIST_VALUE_ID {LIST_VALUE_ID_CHARS}+ QUOTED_LIST_VALUE_ID \"{LIST_VALUE_QUOTED_ID_CHARS}+\" ID_CHARS_NOEQ [^ \t\n"!,]{-}[=] LEADING_ID_CHARS_NOEQ [^ \t\n"!,]{-}[=()+&] ID_NOEQ {ID_CHARS_NOEQ}|(,{ID_CHARS_NOEQ}) IDS_NOEQ {LEADING_ID_CHARS_NOEQ}{ID_NOEQ}* ALLOWED_QUOTED_ID [^\0"]|\\\" QUOTED_ID \"{ALLOWED_QUOTED_ID}*\" IP {NUMBER}\.{NUMBER}\.{NUMBER}\.{NUMBER} HAT hat{WS}* PROFILE profile{WS}* KEYWORD [[:alpha:]_]+ VARIABLE_NAME [[:alpha:]][[:alnum:]_]* SET_VAR_PREFIX @ SET_VARIABLE {SET_VAR_PREFIX}(\{{VARIABLE_NAME}\}|{VARIABLE_NAME}) BOOL_VARIABLE $(\{{VARIABLE_NAME}\}|{VARIABLE_NAME}) LABEL (\/|{SET_VARIABLE}{POST_VAR_ID}|{COLON}|{AMPERSAND}){ID}* QUOTED_LABEL \"(\/|{SET_VAR_PREFIX}|{COLON}|{AMPERSAND})([^\0"]|\\\")*\" OPEN_PAREN \( CLOSE_PAREN \) COMMA \, EQUALS = ADD_ASSIGN \+= ARROW -> LT_EQUAL <= /* IF adding new state please update state_names table at eof */ %x SUB_ID %x SUB_ID_WS %x SUB_VALUE %x EXTCOND_MODE %x EXTCONDLIST_MODE %x NETWORK_MODE %x LIST_VAL_MODE %x LIST_COND_MODE %x LIST_COND_VAL %x LIST_COND_PAREN_VAL %x ASSIGN_MODE %x RLIMIT_MODE %x MOUNT_MODE %x DBUS_MODE %x SIGNAL_MODE %x PTRACE_MODE %x UNIX_MODE %x CHANGE_PROFILE_MODE %x INCLUDE %x INCLUDE_EXISTS %x ABI_MODE %% %{ /* Copied directly into yylex function */ if (parser_token) { int t = parser_token; parser_token = 0; return t; } %} { {WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ } } { (\<([^"\>\t\r\n]+)\>|{QUOTED_ID}) { /* | "filename" */ autofree char *filename = strndup(yytext, yyleng - 1); include_filename(filename + 1, *filename == '<', true); POP_NODUMP(); } (\<{QUOTED_ID}\>) { /* <"filename"> */ autofree char *filename = strndup(yytext, yyleng - 2); include_filename(filename + 2, true, true); POP_NODUMP(); } ({IDS}|{QUOTED_ID}) { /* filename */ include_filename(yytext, 0, true); POP_NODUMP(); } } { (\<([^"\>\t\r\n]+)\>|{QUOTED_ID}) { /* | "filename" */ autofree char *filename = strndup(yytext, yyleng - 1); include_filename(filename + 1, *filename == '<', false); POP_NODUMP(); } (\<{QUOTED_ID}\>) { /* <"filename"> */ autofree char *filename = strndup(yytext, yyleng - 2); include_filename(filename + 2, true, false); POP_NODUMP(); } ({IDS}|{QUOTED_ID}) { /* filename */ include_filename(yytext, 0, false); POP_NODUMP(); } } { (\<(([^"\>\t\r\n]+)|{QUOTED_ID})\>|{QUOTED_ID}|{IDS}) { /* | <"filename"> | "filename" | filename */ int lt = *yytext == '<' ? 1 : 0; char *filename = processid(yytext + lt, yyleng - lt*2); bool exists = YYSTATE == INCLUDE_EXISTS; if (!filename) yyerror(_("Failed to process filename\n")); yylval.id = filename; POP_AND_RETURN(TOK_ID); } } <> { fclose(yyin); pop_include_stack(); yypop_buffer_state(); if ( !YY_CURRENT_BUFFER ) yyterminate(); } { peer/{WS}*={WS}*\( { /* we match to the = in the lexer so that we can switch scanner * state. By the time the parser see the = it may be too late * as bison may have requested the next token from the scanner */ yylval.id = processid(yytext, yyleng); PUSH_AND_RETURN(EXTCONDLIST_MODE, TOK_CONDLISTID); } {VARIABLE_NAME}/{WS}*= { /* we match to the = in the lexer so that we can switch scanner * state. By the time the parser see the = it may be too late * as bison may have requested the next token from the scanner */ yylval.id = processid(yytext, yyleng); PUSH_AND_RETURN(EXTCOND_MODE, TOK_CONDID); } {VARIABLE_NAME}/{WS}+in{WS}*\( { /* we match to 'in' in the lexer so that we can switch scanner * state. By the time the parser see the 'in' it may be to * late as bison may have requested the next token from the * scanner */ yylval.id = processid(yytext, yyleng); PUSH_AND_RETURN(EXTCOND_MODE, TOK_CONDID); } } { ({IDS}|{QUOTED_ID}) { /* Go into separate state to match generic ID strings */ yylval.id = processid(yytext, yyleng); POP_AND_RETURN(TOK_ID); } } { ({IDS}|{QUOTED_ID}) { /* Go into separate state to match generic VALUE strings */ yylval.id = processid(yytext, yyleng); POP_AND_RETURN(TOK_VALUE); } } { {CLOSE_PAREN} { POP_AND_RETURN(TOK_CLOSEPAREN); } {COMMA} { EAT_TOKEN("listval: ,\n"); } ({LIST_VALUE_ID}|{QUOTED_ID}) { yylval.id = processid(yytext, yyleng); RETURN_TOKEN(TOK_VALUE); } } { {EQUALS}{WS}*/[^(\n]{-}{WS} { BEGIN_AND_RETURN(SUB_VALUE, TOK_EQUALS);} {EQUALS} { RETURN_TOKEN(TOK_EQUALS); } /* Don't push state here as this is a transition start condition and * we want to return to the start condition that invoked * when LIST_VAL_ID is done */ {OPEN_PAREN} { BEGIN_AND_RETURN(LIST_VAL_MODE, TOK_OPENPAREN); } in { RETURN_TOKEN(TOK_IN); } } { ({LIST_VALUE_ID}|{QUOTED_LIST_VALUE_ID}) { yylval.id = processid(yytext, yyleng); POP_AND_RETURN(TOK_VALUE); } } { {CLOSE_PAREN} { POP(); } ({LIST_VALUE_ID}|{QUOTED_LIST_VALUE_ID}) { yylval.id = processid(yytext, yyleng); RETURN_TOKEN(TOK_VALUE); } } { {CLOSE_PAREN} { POP_AND_RETURN(TOK_CLOSEPAREN); } {COMMA} { EAT_TOKEN("listcond: , \n"); } {ID_CHARS_NOEQ}+ { yylval.id = processid(yytext, yyleng); RETURN_TOKEN(TOK_CONDID); } {EQUALS}{WS}*{OPEN_PAREN} { PUSH_AND_RETURN(LIST_COND_PAREN_VAL, TOK_EQUALS); } {EQUALS} { PUSH_AND_RETURN(LIST_COND_VAL, TOK_EQUALS); } } { {EQUALS} { RETURN_TOKEN(TOK_EQUALS); } {OPEN_PAREN} { /* Don't push state here as this is a transition * start condition and we want to return to the start * condition that invoked when * LIST_VAL_ID is done */ BEGIN_AND_RETURN(LIST_COND_MODE, TOK_OPENPAREN); } } { ({IDS}|{QUOTED_ID}) { yylval.var_val = processid(yytext, yyleng); RETURN_TOKEN(TOK_VALUE); } {END_OF_RULE} { yylval.id = strdup(yytext); DUMP_PREPROCESS; yyerror(_("Variable declarations do not accept trailing commas")); } \\\n { DUMP_PREPROCESS; current_lineno++ ; } \r?\n { DUMP_PREPROCESS; current_lineno++; POP(); } } { {IDS} { yylval.id = strdup(yytext); RETURN_TOKEN(TOK_ID); } } { safe { RETURN_TOKEN(TOK_SAFE); } unsafe { RETURN_TOKEN(TOK_UNSAFE); } {ARROW} { /** * Push state so that we can return TOK_ID even when the * change_profile target is 'safe' or 'unsafe'. */ PUSH_AND_RETURN(SUB_ID_WS, TOK_ARROW); } ({IDS}|{QUOTED_ID}) { yylval.id = processid(yytext, yyleng); RETURN_TOKEN(TOK_ID); } } { -?{NUMBER} { yylval.var_val = strdup(yytext); RETURN_TOKEN(TOK_VALUE); } {KEYWORD} { yylval.id = strdup(yytext); if (strcmp(yytext, "infinity") == 0) RETURN_TOKEN(TOK_VALUE); RETURN_TOKEN(TOK_ID); } {LT_EQUAL} { RETURN_TOKEN(TOK_LE); } } { create { RETURN_TOKEN(TOK_CREATE); } listen { RETURN_TOKEN(TOK_LISTEN); } accept { RETURN_TOKEN(TOK_ACCEPT); } connect { RETURN_TOKEN(TOK_CONNECT); } getattr { RETURN_TOKEN(TOK_GETATTR); } setattr { RETURN_TOKEN(TOK_SETATTR); } getopt { RETURN_TOKEN(TOK_GETOPT); } setopt { RETURN_TOKEN(TOK_SETOPT); } shutdown { RETURN_TOKEN(TOK_SHUTDOWN); } } { bind { RETURN_TOKEN(TOK_BIND); } } { eavesdrop { RETURN_TOKEN(TOK_EAVESDROP); } } { send { RETURN_TOKEN(TOK_SEND); } receive { RETURN_TOKEN(TOK_RECEIVE); } } { trace { RETURN_TOKEN(TOK_TRACE); } readby { RETURN_TOKEN(TOK_READBY); } tracedby { RETURN_TOKEN(TOK_TRACEDBY); } } { read { RETURN_TOKEN(TOK_READ); } write { RETURN_TOKEN(TOK_WRITE); } {OPEN_PAREN} { PUSH_AND_RETURN(LIST_VAL_MODE, TOK_OPENPAREN); } (r|w|rw|wr)/([[:space:],]) { yylval.mode = strdup(yytext); RETURN_TOKEN(TOK_MODE); } } { {ARROW} { RETURN_TOKEN(TOK_ARROW); } } { ({IDS_NOEQ}|{LABEL}|{QUOTED_ID}) { yylval.id = processid(yytext, yyleng); RETURN_TOKEN(TOK_ID); } } #include{WS}+if{WS}+exists/{WS}.*\r?\n { /* Don't use PUSH() macro here as we don't want #include echoed out. * It needs to be handled specially */ yy_push_state(INCLUDE_EXISTS); } include{WS}+if{WS}+exists/{WS} { /* Don't use PUSH() macro here as we don't want #include echoed out. * It needs to be handled specially */ yy_push_state(INCLUDE_EXISTS); } #include/.*\r?\n { /* Don't use PUSH() macro here as we don't want #include echoed out. * It needs to be handled specially */ yy_push_state(INCLUDE); } include/{WS} { /* Don't use PUSH() macro here as we don't want #include echoed out. * It needs to be handled specially */ yy_push_state(INCLUDE); } #.*\r?\n { /* normal comment */ DUMP_AND_DEBUG("comment(%d): %s\n", current_lineno, yytext); current_lineno++; } {CARET} { PUSH_AND_RETURN(SUB_ID, TOK_CARET); } {ARROW} { PUSH_AND_RETURN(SUB_ID_WS, TOK_ARROW); } {EQUALS} { PUSH_AND_RETURN(ASSIGN_MODE, TOK_EQUALS); } {ADD_ASSIGN} { PUSH_AND_RETURN(ASSIGN_MODE, TOK_ADD_ASSIGN); } {SET_VARIABLE} { yylval.set_var = strdup(yytext); RETURN_TOKEN(TOK_SET_VAR); } {BOOL_VARIABLE} { yylval.bool_var = strdup(yytext); RETURN_TOKEN(TOK_BOOL_VAR); } {OPEN_BRACE} { RETURN_TOKEN(TOK_OPEN); } {CLOSE_BRACE} { RETURN_TOKEN(TOK_CLOSE); } ({LABEL}|{QUOTED_LABEL}) { yylval.id = processid(yytext, yyleng); RETURN_TOKEN(TOK_ID); } ({MODES})/([[:space:],]) { yylval.mode = strdup(yytext); RETURN_TOKEN(TOK_MODE); } {HAT} { PUSH_AND_RETURN(SUB_ID, TOK_HAT); } {PROFILE} { PUSH_AND_RETURN(SUB_ID, TOK_PROFILE); } {COLON} { RETURN_TOKEN(TOK_COLON); } {OPEN_PAREN} { PUSH_AND_RETURN(LIST_VAL_MODE, TOK_OPENPAREN); } {VARIABLE_NAME} { int token = get_keyword_token(yytext); int state = INITIAL; /* special cases */ switch (token) { case -1: /* no token found */ yylval.id = processunquoted(yytext, yyleng); RETURN_TOKEN(TOK_ID); break; case TOK_RLIMIT: state = RLIMIT_MODE; break; case TOK_NETWORK: state = NETWORK_MODE; break; case TOK_CHANGE_PROFILE: state = CHANGE_PROFILE_MODE; break; case TOK_MOUNT: case TOK_REMOUNT: case TOK_UMOUNT: state = MOUNT_MODE; break; case TOK_DBUS: state = DBUS_MODE; break; case TOK_SIGNAL: state = SIGNAL_MODE; break; case TOK_PTRACE: state = PTRACE_MODE; break; case TOK_UNIX: state = UNIX_MODE; break; case TOK_ABI: state = ABI_MODE; break; default: /* nothing */ break; } PUSH_AND_RETURN(state, token); } { {END_OF_RULE} { if (YY_START != INITIAL) POP_NODUMP(); RETURN_TOKEN(TOK_END_OF_RULE); } \r?\n { DUMP_PREPROCESS; current_lineno++; } } { [^\n] { DUMP_PREPROCESS; /* Something we didn't expect */ yyerror(_("Found unexpected character: '%s'"), yytext); } } %% /* Create a table mapping lexer state number to the name used in the * in the code. This allows for better debug output */ unordered_map state_names = { STATE_TABLE_ENT(INITIAL), STATE_TABLE_ENT(SUB_ID), STATE_TABLE_ENT(SUB_ID_WS), STATE_TABLE_ENT(SUB_VALUE), STATE_TABLE_ENT(EXTCOND_MODE), STATE_TABLE_ENT(EXTCONDLIST_MODE), STATE_TABLE_ENT(NETWORK_MODE), STATE_TABLE_ENT(LIST_VAL_MODE), STATE_TABLE_ENT(LIST_COND_MODE), STATE_TABLE_ENT(LIST_COND_VAL), STATE_TABLE_ENT(LIST_COND_PAREN_VAL), STATE_TABLE_ENT(ASSIGN_MODE), STATE_TABLE_ENT(RLIMIT_MODE), STATE_TABLE_ENT(MOUNT_MODE), STATE_TABLE_ENT(DBUS_MODE), STATE_TABLE_ENT(SIGNAL_MODE), STATE_TABLE_ENT(PTRACE_MODE), STATE_TABLE_ENT(UNIX_MODE), STATE_TABLE_ENT(CHANGE_PROFILE_MODE), STATE_TABLE_ENT(INCLUDE), STATE_TABLE_ENT(INCLUDE_EXISTS), STATE_TABLE_ENT(ABI_MODE), }; apparmor-2.13.3/parser/parser_alias.c0000644000175000017500000001166213502024172015320 0ustar jjjj/* * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 * NOVELL (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. */ #include #include #include #include #include #include "immunix.h" #include "parser.h" #include "profile.h" typedef int (*comparison_fn_t)(const void *, const void *); struct alias_rule { char *from; char *to; }; static void *alias_table; static int compare_alias(const void *a, const void *b) { char *a_name = ((struct alias_rule *) a)->from; char *b_name = ((struct alias_rule *) b)->from; int res = strcmp(a_name, b_name); if (res == 0) { a_name = ((struct alias_rule *) a)->to; b_name = ((struct alias_rule *) b)->to; res = strcmp(a_name, b_name); } return res; } int new_alias(const char *from, const char *to) { struct alias_rule *alias, **result; alias = (struct alias_rule *) calloc(1, sizeof(struct alias_rule)); if (!alias) { PERROR("Failed to allocate memory: %s\n", strerror(errno)); goto fail; } alias->from = strdup(from); if (!alias->from) { PERROR("Failed to allocate memory: %s\n", strerror(errno)); goto fail; } alias->to = strdup(to); if (!alias->to) { PERROR("Failed to allocate memory: %s\n", strerror(errno)); goto fail; } result = (struct alias_rule **) tsearch(alias, &alias_table, (comparison_fn_t) &compare_alias); if (!result) { PERROR("Failed to allocate memory: %s\n", strerror(errno)); goto fail; } if (*result != alias) { /* already existing alias */ PERROR("'%s' is already defined\n", from); goto fail; } return 1; fail: if (alias) { if (alias->from) free(alias->from); if (alias->to) free(alias->to); free(alias); } /* just drop duplicate aliases don't actually fail */ return 1; } static char *do_alias(struct alias_rule *alias, const char *target) { int len = strlen(target) - strlen(alias->from) + strlen(alias->to); char *n = (char *) malloc(len + 1); if (!n) { PERROR("Failed to allocate memory: %s\n", strerror(errno)); return NULL; } sprintf(n, "%s%s", alias->to, target + strlen(alias->from)); /*fprintf(stderr, "replaced alias: from: %s, to: %s, name: %s\n %s\n", alias->from, alias->to, target, new);*/ return n; } static Profile *target_prof; static struct cod_entry *target_list; static void process_entries(const void *nodep, VISIT value, int level unused) { struct alias_rule **t = (struct alias_rule **) nodep; struct cod_entry *entry, *dup = NULL; int len; if (value == preorder || value == endorder) return; len = strlen((*t)->from); list_for_each(target_list, entry) { if ((entry->mode & AA_SHARED_PERMS) || entry->alias_ignore) continue; if (entry->name && strncmp((*t)->from, entry->name, len) == 0) { char *n = do_alias(*t, entry->name); if (!n) return; dup = copy_cod_entry(entry); free(dup->name); dup->name = n; } if (entry->link_name && strncmp((*t)->from, entry->link_name, len) == 0) { char *n = do_alias(*t, entry->link_name); if (!n) return; if (!dup) dup = copy_cod_entry(entry); free(dup->link_name); dup->link_name = n; } if (dup) { dup->alias_ignore = 1; /* adds to the front of the list, list iteratition * will skip it */ entry->next = dup; dup = NULL; } } } static void process_name(const void *nodep, VISIT value, int level unused) { struct alias_rule **t = (struct alias_rule **) nodep; Profile *prof = target_prof; char *name; int len; if (value == preorder || value == endorder) return; len = strlen((*t)->from); if (prof->attachment) name = prof->attachment; else name = prof->name; if (name && strncmp((*t)->from, name, len) == 0) { struct alt_name *alt; char *n = do_alias(*t, name); if (!n) return; /* aliases create alternate names */ alt = (struct alt_name *) calloc(1, sizeof(struct alt_name)); if (!alt) { free(n); return; } alt->name = n; alt->next = prof->altnames; prof->altnames = alt; } } int replace_profile_aliases(Profile *prof) { target_prof = prof; twalk(alias_table, process_name); if (prof->entries) { target_list = prof->entries; target_prof = prof; twalk(alias_table, process_entries); } return 0; } static void free_alias(void *nodep) { struct alias_rule *t = (struct alias_rule *)nodep; free(t->from); free(t->to); free(t); } void free_aliases(void) { if (alias_table) tdestroy(alias_table, &free_alias); alias_table = NULL; } apparmor-2.13.3/parser/subdomain.conf0000644000175000017500000000365213502024172015337 0ustar jjjj# subdomain.conf is a shared AppArmor configuration file that is sh sourcable. ################## AppArmor init.d configuration ################ # Move this to /etc/sysconfig/apparmor eventually ## Path: System/AppArmor ## Description: Enable the OWLSM extension to AppArmor ## Type: yesno ## Default: no # # Enable OWLSM extension to AppArmor? # OWLSM is an extension to AppArmor that prevents processes from # following symlinks they don't own and creating hardlinks to files they # don't own, in an attempt to prevent /tmp race attacks. However, OWLSM # can break some applications, so is disabled by default. SUBDOMAIN_ENABLE_OWLSM="no" ## Path: System/AppArmor ## Description: Enable the AppArmor event daemon for reporting ## Type: yesno ## Default: no # # Enable the AppArmor event daemon for reporting? APPARMOR_ENABLE_AAEVENTD="no" #SUBDOMAIN_MODULE_PANIC=XXX #This option controls how subdomain behaves when the init script attempts #to load the AppArmor module and fails. There are 4 options #warn - log a failure message. (default behavior) #build - attempt to build the AppArmor module is the module can't be loaded. # If successful # the module will be built for the running kernel and loaded. # If the build fails # a failure message is logged #panic - If the AppArmor module fails to load # a failure message will be logged # and the machine will drop to runlevel 1 (single user) #build-panic - If the AppArmor module fails to load # attempt to build the module # If building the module fails # panic (drop to runlevel 1) #SUBDOMAIN_MODULE_PANIC=warn ################## subdomain_parser configuration ################ #SUBDOMAIN_PATH=XXXX #This option specifies the include path that the subdomain_parser will #use by default. If no entry is specified /etc/subdomain.d is used by #default. #SUBDOMAIN_PATH=/etc/subdomain.d apparmor-2.13.3/parser/techdoc.pdf0000644000175000017500000071375613502024374014634 0ustar jjjj%PDF-1.5 % 156 0 obj << /Length 1320 /Filter /FlateDecode >> stream xXKs6 WHDHujylIC#3&z:DJv\9f^")4@|@Ļ%# >܏Tb$%t;9].OEYy~22bEGI1IEܮJW SZ,?'?6rDipO0K1AV#&w:TvAS26brZe>0 Aax&\m3}E*^&!#H8]5m|awDsg\<O6's[h;$_*kPڮ_;S bТd$-n0ѐ12^/<إHg)h"r@ <_7|$/TwQGw˂X`0R0 o D?a1piY&m ,G:0l:ڬeg؏n.װﳟ;U܀1̊pLTf tؾk "F?Q:ũ+c5snv0Ȋ*T/{Lɷhn++~ju[Pаi+CV!aVztep~U#m vsnîN:L )Ywg}-$c+rr쪂mF5އL צ *s/E6F &6 :BHOHL/]gMnLvHIwNl&wTGNx' #R@}2 A4R9gw @ߤB?k瘬}y:V>fnOk5v(sN{U)Y:5TzE\w 5Q쌴n =ov޴=f/ɼ*W3p URƄϛ-~tʳIO9+ $vjk}ӚldC&e^DHXۆG $՚BG7:wxq֪ N ݔуMnO _%W&KWVIiP )Ly6(yR8yQDHD8#?V֓?@k endstream endobj 173 0 obj << /Length 2800 /Filter /FlateDecode >> stream xڅYKs8WTH#>EΜlejv+L|h?u7Dʡk/h~~ Ct܄>Nhs dèW/A݅a8 ƾ跚u?o}E8lvQϣPVӪ]&xvb.]-]١݃ ]tw|זXn]ij!acйкGO,}cq"ME~7B1(q<L[Nb~màxN.@ҽFƲ0ow1 EG~ֶH:YX]j%וF>w-a R4a*;W 2 wʮ.TblTZuW~"y95:cBlp8J3X?֖B#=}L ODBA7Z! Y* "InEl9`IWI~! b!Wn(aI Y0vr"Fk:F2GcHK6aYwkg1,0HDoDXD`O#\r~!K,CE|"Ya9ȭ'>ɇ{%h+$ Y#g'H%;P\DL7Ĵ]s7HoYO7J7T C@,ť(#&6tBiQȟp,_>iO;5(UAjOmIJЖ}*tI6:!LZQ^d0VS9$[eF7!WlWAn< E/2uǵ: RQi=KF dE͕]: KB\ KEs~Va/ѡkQ(Hl9+8)U@-J7$7c׿F¢ݭZnA{E N}7q(lIɮT:L!8:KPj|9*Q+kp s+z"GhT^kxM=tkr˥FR3vb#I1}t>Lo>+aYhs2[]ӉHq'#=}|]K#iFCf4$ࣤTp1|xAm@W;)uMR*KJ_޽][.S(TO|(#6X_F<;9kA='Ea( t`fnBgIEّYio5s͔^DR^a< ̦ ~ЯuBM!pyߕ>T ӵ^|5!%N;8;TA-=K HWB}AA,~ak}Ӓ'mNwqrpvz8>ݓ߈ \͠{@RE h/*-_^Fb%8b bj #AI)Kz8šnSBs.d=x7]$JW miοxUќ_Et`8''*? &xMNi& C%KN4]MP<6!ÛgC:SLF?dr3]SQj8 ^$r8/B=u#IeD|_pq)/]1_veS0}N qAZ.=:#z_ݜ0p &KSV)}9gMhzMRLjRvC+ԱsӔ7TlZqIi(p׺|k_#"q:j}ɗIsɛd^9Ϝwsvz2MV?j) SP_@VQ,_ڃPf.FsّK RB 'toQn*H`%,b2D6jEU3;6tQ3JɫyzrEfz_N 7>(>Gܽ cd~MB /S][Ma]%`+jZz텳}#`~C9SnaPi ,;YV_0;.7g DQ^zm Ai xRb|IGO30#g8Ug-&{\Z_%\he>FCTB0 _N> endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 808 /Length 2128 /Filter /FlateDecode >> stream xڵY]o}ׯ 0undk.mFbl")T6Fs$vȢ `yDj{ܹ3T$ɑ:J)Iѓ2?4TTJ"mBkM;M{2D+F4_ YiX: d!HVfa5 ^:N^["΀xZ ɠ7EhOL8!1=2R.a|af>eTlL@"߉318Vq$6zK>& 8SH&^ 41Bpf+M"k]^m #I KV[ !8V~g=l<{p]ǚX e f{x%v%oau ^®sQ!B>CpgD9 V#*Ωh8'])˦ߵp飝>Vu͡uEnZwuCU~`[Z7w^ҫЍ~+7U-XLmvz]uT6+:nMW1<{{~쟿VZotRV? ]E= fg۲n|TeS7W?Y]u1޵QƜn̞zEO[t~}!pv. 8UyP yu4B;75@\Gm-W3HpFl7U?˚ܴP5.^?zҜhmWT➪w4 qotȠ[o776##_WWjj*7C*-+PqZ2 AO"a9P|`qWT43RXlsPgg6!ڱƩHPA^ *, jTTLRR>`I-4?O,(j^ZCh DR`ӭqN:zs$̟mELLŋY.[c%zȫsTBe|k*xP|'M252ԮSRn̟q5vR(BH& \O:bMLiN'̟r5j>5X]N \Ϲ%Tiɉk\,MEZ_hk!)l|xbV.|< 2h? 7D$6Z)%J ~`5-B3IȻz-%/L旊R_aXfi_aI)_ q"_$K0/5$4Й7IOsΧmOٵ..~elMb: ~8v|F)է냝Ђ-(|> ;GM'OaJY*dWx[>yx.v[Q< * +^F!ayœ endstream endobj 180 0 obj << /Length 2698 /Filter /FlateDecode >> stream xڍYKs6Wtrմ#7Tak\Ltv+VKI=myS `psk+2.K?O]d~jw>InZg^=} Fg'yգtm&RIkI>3-z.?kL~CMZ2i'ɯQ OiPhGsAȫZʰr1ȻoatbDsy @ǚ.A[/d8ze;=a#zowg>k^Y)EI2 SuyOb~C l4P!cC0 Ut*4YgZ{'Г@qɌۇ}0mk{3Zi>7- Iz7ؘ?x>ls:@r6~UӞBqM : T2s UW7VY40~Ef7?]?DDڡk.oS|܈=RIĨaBS[8Ve'ץռ-wO8pFx )u5M) S/\r<8mb 42A`)3eR~myńyܾ&$}pd4BL'DH@ 6ptO"DX\ 78eD3[2R̩ ~6Z;`SNZhPf_][eŚ|+iRGM1՝IOҹ^F;-UYNU>_2)-ء2lZAX0hRIθxS:=tF33xeںUҽb68kkgo q@C&0KN^_V_LWbr92M" r]'xIMbtɌSnjZE[إB1S[2m&rGu(tYʋtU;}6L,ʥ,Dsu?ѻ41$vY}~b޺׋B5B?(C-?:kќtݛ5=R{\(;$}$˵P_^\ hz$/1v}uo*!ȉϹNvnW]> stream xڭYKoWm9{ҮAp"!li6ԫIDŇ2~U_~PJ̢lww /hF}q:JJi63=|d枪}Txu(&ݎZSUxfsO-u0vN_Ǯ:׻ueȃ:z݃?}wGxJ~Qb?(>rjeyZ5Cn_Azy`l?0VQp,sVNA똴jnu$jwn t>jao({BfW *Ɍ#IvT'qjȶ.ػც/+b%8雖CH^NW47 /W&P5ӛHS2 685L} MLkg=yr]ۑ]!#<ŇNt&~$/bo08E rr:}̣I+È<5DJ[[ (I52,\ :ȟxg22u#Ef3rѠ 2O$pH0rN8|s_p+r\׽["P7Ӓ`#9jưZXYX0Ra8xXp:[HgeAV *Jeބĕx-ʏY<5ݑwiwKւysH ΁XL3OVݵbw B8ywK٠yvmjb$v JΗ NѰd eY9V}&Ի#ZA?V=HӥzPH"C bh=9 Eכ(^{.%AC^ݥQ a}55 e;.KȬ^ꗗuIg i֡~cQ0 -o @Uq꫃n( 1*SaVyCx4/]=0:@dE]ErP9<2iQ{Z1g*̶'@/g0pU-TTfp*ipqZ`7  r %h/M4JmG5n4JlJbA>ݽ.äòEyQ?Ta!@M~:߽òX XZav=y|O?Slbf1bC2\yFZ?iyn]qoJTJEv*Dw>35 ٵf` ]8Kj J.SWy-뗋oU6Ɩ('w;$ #diK^,YUOBNM@Z > stream xڭYK6ۺe}4CƏeg@~(FrKY(")W.IuQ.ICc\=5?$-s%?TC]%w:d̴&׿<:Ncz.4Kˠ"2X O"<鬿)!vt<>i4+_l>'.NɅ[,ϭYZFŽ=[@^adxC䭬-NqOCLtLS8$#72qk^EYU ,dX FrB t͵>7)x* w1`؜ir$}Ξx3|'ںə1Jhhc2렷 om(r 7؂,v 퇸I9)}LGs o+QhKǧ<tOmH$?y~֧*i˧e2HƞdƳ0⫢2+מlˉ&Z'X>%rafzǵ>tbzh6[QmW}z,HGr'-**hؤ ɷ~TUUVG{vm>}ߌH0Hyt^=OWaaҌb-9 1a oHQ| b&, )،NÇϢui5g?Ԟi,\Nj |:Y\5E|ԹuLt‰vnĈܡ}~-jB](A#p2*$n-_FoWY ]M9ZK27006:Y/uwX4[}™7:߸DbG) _] n^J:Sxp '*8I3S# &qFXd~Xy~@o!QX&\XYR +BaM L \A:8?"+upHќOf]~FC4H  LUTQMH˔BVw'4:*ơ^B<Հ\ 3:t5n{Oú A#t49e^ JiXMPs$=Tz\<+osеأӯo#"+EOJ8f$*hM8&Sq !X<;.>?T2d SJTS\$ǐsi6B-Ԅ+!#9%9'b }$GWg)̘P=Ѡ i)`RHnmnlxRZ0a$z&HВ$@7J |C/oEwIjEiUu+ -HQU[2εM2뚘fVU8~rk|p:uCVn&b f= P~?'tj)7Κ9yfMS((3 T%:[Pݿ:.n7benZ-\eEuZ.) Laɘgt!ɪD^z-U5iYz{J\%JK|w>+ Э< ǔ_e뻭 \|G%]G4*na'FPr3@iI#I лy6jV$Wt(ӻhކENpפB٘a2 )1inZ~ҘU I1jlt5M}E^W5ш.) 1E:PH:WK8]~s<#,z.Tš4$u~B@QN ڤlyjAo~"~.Rz ƃ ~R\,)#Rݬ LgY.^nܷ=!+>y2E endstream endobj 198 0 obj << /Length 2453 /Filter /FlateDecode >> stream xڅˎ۶v0 ĊDQԬr .nc1;Jx_,ٚ͘:<<<?o}*U\eEt\&jQ$&NU,;\e:n{<:4j+UFk ީsxҺ>6u7 %:uׂlvvϋdJӸsf#f$[>w?wXvDx5Ky:O c.KрT%Gic@Jr@@(SUv}8f9R#7NEcDhf5ҽ2El@=,}cT:(8O=!7fMƔSM Q*c!)B-CgMЅP Kw^n_ >gQ E|ӾI318uL]뺞YᵊL@V I ,)R'{ v+Ǻx 2[vv6+ xiKΥc@%'I$CJ)DS`=?U67NbIp|<0JwD6!f|8[^Q_ ύ\׾,!}OМx5m$a+k_ -dVh6SZipYeJ _dчC{\ _cǰ! pf3Damss Hl3n{<oL1QDO`q5v# 9A9erf[UUd /[a(&@hɑtvd Н{g0^`28U6N /|H_Z$xq\rEЁ?!Hw}F1eIl5^ϨBEhxqqj닃SBP@0 D֋גsM+%'2:&(DKkIYVJ^ݲs߈6T!WN2c?z]hZ8Nav{rvh+˕,:g[CAx~69fָǽŖ[ñ~ {r>0FUrT2 `z+RzI3 i@a8Ϫ6٬ @!}R--y_I`„0|_Os )v, U+ t++K2ZyFs{]bY1iUq*pk/&(ė, 8E {G99ZR6[zK;;(TlҒG\N^`Oԃ P8i4 ݯ Gc~X"V|w@~u*yOUȄm<O:KB-=R0aV50^L`vfAvRnUh 1ZRatH<&TiYz|l3C !<Ǧ%KɯcZМCjR"]Q[]d䊭+)@%-|X3qBTQIc9_˸L9 g߹pݬѦCJa NrWl1jNr*>CGD}=Ÿ{`C% Ol߰jhP,C"Z ǃ8@Rd MX909^;?8t$ܳ[z:`x,KOXɩ0[/ d _8qJң BV7iYRY4%n"lp.R36U2K7wo endstream endobj 202 0 obj << /Length 2679 /Filter /FlateDecode >> stream xڭYms6_oo&IRg7m?mq" I]삤$F5F+9KៜIoDgNZs5+-`Y*tgOazf^~՗=R-R᭟"T6{<uZbG\u՛Dz2{ J,XIst=+˥p^_,Bg9im. 2'^'MՕ';_1b.^]Ľ2l ^.l,r[uRl0IY#vK\+tlҬN}xgNx.Xv-/c>n(v{} wA}P[+r.ͅM>2{2`nKR&k4%M>2&2K`n~ӟ}cKǻ%ְNY2{Ke8 Tf;_cizgV\q>2{2pl=UeB=n#e[}ZxN*;| {9^k: n$hW.02Ҹ@0sOkL~&̴qi+Te&v˂YrMK8(IZfӤ]A u+(%=,0VD@!{; 01-ehH.~ Lm&ybJy\ - Fa t˲dAxGAAz$#{XUp uM#Tc+Yw>.+'| eH@G]>=-9ܒ+8܄kźbЭZ'Vm%3j(kp:X]eK:"U4.ٵc3R{Qr:7\>JܢBQ*Yo)Q iyZLx8xb& ozy6,ޞ9RަĆS7qݣuM>ǡ}<#LO3 =kl7i ^n;ZA+98 Q:f2"2bWҏii'"vW'+nּCMw#So4{`WcjؔOځoE[u@Ux!Z 9QQ~[jtSZ34B*FԱg[A4D} *͒G?8ȯM SR D3,.6LrGix2SN]bTC F|؛L0G5'D| 0qShEX]i^g|wuR(AujϣQhf}jctT\lc}beםH7F;r7B0/)@ > ;4H 2yJ qI endstream endobj 208 0 obj << /Length 2532 /Filter /FlateDecode >> stream xڍXKϯQ=h=6 2A fz&Zw^n%ًEd_WͶ)ruXeVir]+5vq($4(TrOJ̈]~3h3 GÃoqv:כN۬}UdٶXG:*j1"w&>L<nlA=erԞ.kרugd]g0Xfpv;D%1;רQuruw!5貰@tv`N FKYuRb#-Kr$q6NQFˮS,d;xzOagoi"ȡ̄A7כ,&L=9lVeD^v ۢ ? jۤ\ퟄy[R5pb ؼL*?GͳkX$T)&(;YP%t[d>x~Mwi?OYNRIo.n[g?e'_PM趵h;w%*:nä*x=ώda4I@m9>RjAs+kdc仒 ] "7Q[o\NwNEh|eC#omUVnC2\$܆0 wAƺdGY 8!-VܴR_ތG13O7&1VŶ.ԫTxSxj9C^G㣹P_\l4fo;k~p)s(Q IsW%di0yf嫻P,vDZWXv!=Ԑ t!xYI|bH U,}hba E H8 SzХTi04S b  .vJ"V+41j^m惊m j|e<_7SOs0 8#g}m\-796^de{E3:{F58a#4cʱ)"t'oeA Q`U L ~:8k!A;ߎ̈7k3]| o\#c AQHAڣ?4urz8 75 bO.(FVYUePF `EjghM oL%"c$b:h5GQ*Tbdg>'%if~B)P܉^ c2џ/ [z:qdwpY&F]@1k9SCKC'Wr dL=|wv9V *qO h0]5S&$,Y/쬞n+q,du~RIs;JI4 AE( Q׮';@k8tSvUj=Fv6c8t Š?Oy1x'vi"vl:#ȷyyUKVP6{^0-39Wj됮7)NtY5r|P\-0]ƫa宣z5 ƥA͗%QFP!'^'jY~¾) czf/$vTNcGC`ǺMU0#ǹVOv or^e/ewOU迼)sU0< }تPaȲnQVU_һO~7c endstream endobj 214 0 obj << /Length 2483 /Filter /FlateDecode >> stream xڭYY~_G0<ʥh7l? ,9 hk@ڪ/LO77_*<-|~`ن=zt.8f f`;q䶷=U_م_1|CH>4m^Wb5(-wK}b}Ц$ө1;ZP|6#v: GC 龜єSI=֭f37<(_Ly`8(<]jDpVC),pgY c3 tu@%)"(E1eIugl$ߑ*+8-sY|,ۣۺ,O[ќ`񞆞GE)#˚; ov8`eDB@\h!MOvd|ڊˌs^;ä3 gnO]wOf"bՃ>8)1Y`ƵښQCv #ȴj]7y=rBvȎkk$ᕢ"m); 5v~@O-EeR < x>~4 j;s✂/٣Cd|:)w!ӽ-wR^,(hH$# ` yM( u zxVgU%4MFݘ`W F)ԄJ*:gGy5W,~'4mia6ܰ[ރe+ʢ/Ğ?Dd 0p.6ϖI<|hvӸ}*Q`'CycMr&,d4tmJBvz$@r=c;+رyGF0.}Q60ND*q)l g‰ӟѩbb=a=]kaѤ g7`բg;AGFooj/9]1Kc%ɪOZ$,rr#nӉhݙw~ B&M **bAAqiV_4K#1Qqx%+0&y e \#4`?\?$ aX'7%!SҺFG+L?Wy@R\ +JJ%rE._- @Ql݌e1w[E\pb9a| spoAW{g1CuRg,k`Y 8m? oԝ’WPVza`[,M*anuM6?ME)ۛ~ 6 7On_LfsZD1i{^ir燇wx7oޥ>-bH42czU2R7@8,/j l2v*W CVrQytFRo2I3 ,3m{7Y/?P΂ưNKWvtl=?`ʜDP65_wl2-E'R5IYЯ|bLb ![v?] Y>wZ48Af;* :f?9Wg36R}70zDծvVbmEf{Q`*pMFʏpTP>"zsJb6o|uim%ζBo8go8.P /Bҧ,7 pGGҲÙ? AfYUܺ~^}e\&bR)㒉tj8=dؙŽb9ߝ!gʪ<08譩Ed2z+)2CTɥ<K\c(NAYrG)Й g*#y endstream endobj 220 0 obj << /Length 3112 /Filter /FlateDecode >> stream xڭYmo_Tne$* \ ")HB+^zH󹿾Fv8"p8g_]|ME&V:4Qƪ՛$m4xV$O{Amk=pu}??Gn >ju0Uno_ta 6؄q?΃,}I,;! FZN9TЖi,xplxezL`֍;:IX򲪎5L;6(+{@e"&oqپ7Qv57 GnQx RG|BU߁NR7s3SM{ B^JvLHqʎecW5xd'L3;NV{itV\Wve[` +e(($<|02 /hUw& zֶlx%+ٹi&kZ%v}&0ɻcX?DCpB4푛pXи  ϨI%6ٺ [7jpɓk\hgѹ]#SUZ&1$ OuMzyy./z0s>ފ+.6 i3|Ke)kf()?BFRdKASI ܊r 4hr*u/׵H oEz\u|-biTǁX",/xp8ٚFKvv8FB5E_* Óv_d6\Ln/b|3ל Iu3>㖿'heԼZWh+lff@cYOw;`aJ͕~-3!G5NGF,4/BxNv1A`+'qd,CÖ #|0*@(e͵<^:bEpHqREt&2BhgG>sj&B9Z>aKcƕr~x97H/N~=j9nJ$ޚ:dTFYZ]/}yn~4~7zwwU 2DxdqjUAj~%0bB(6'nTXGfs{/ t8ʖ& eG**v|͏Y4y>()8s? nڎGC[Zn  ,r~B;5zEJ!\R9pa`"ES~B"{* =?횙yG΄'lؕy{r yx1uB9\jN]x\`Hx "KB$ht dJ )ga僫dG_"O TtY,R/M}mIz -oڃ}F4Rdf$iO#:JA_9qtUªjKe#a Z^)X0bHWʂwsљ32evE쀃nCIX%\%WV/}MNj㐴^9YGra,8Bd1~qiĒ,-|6,=#ӮV)d’`pДap@n%P.Kaƅ  ps*|eۄKsqצs8sKBH|-,>=,qLESd@ Ts8W .0JkJ $<'=ǐM9Q HMea[mUhb_ NF@Ž=l˲] (¢TWyh,iͬ5 e`!Yn!/|`y٘CHLU)_<{2shO `I5?=]Y;;rN)\M|.K|,eÑNE:4d!&=s |&]</$H.j̣Q߬>B+L%A"swNGq#)D} AMyzrCV BQ0x={9o`Q;ȥMǡC32OLqt`t8-GUi_JL5cWS*[å)^p)!^X25STA 2N*┯% @91yDJ" (cyoF8(/F$YW||=A{Yl;? l O/tHq2Y"z!31yȅ Cý񓐐` OD;UKgYhrqGb l endstream endobj 233 0 obj << /Length 2267 /Filter /FlateDecode >> stream xڭnF_!}9@YwbňYS!܆Uqk͹|Ea~$,6*da}¨^GQεkսmXik?l6O?'8yS*23Y"Tp8Н 4 ov|lpx GkLv,x::AP?jθQn!۷{9hEe,LmtexanMTu'b}+Lm$^'* ~@QFDEA'4u'zD|?-hQgǸwO!c*RrڒU n?J;@,\iAwN z0B4M5z[[]nv ]|g!#r=A{" < K(0H?tqfLL" l,6O,vP$,dB.b>bB"P0'ru[h)ok>'ٔ7ɦ[(GPrȢy<wGPʼْ!?MF5;++eihv@lT݀vNc iO:IaN3-9x*'RNQ<:e S_dߡ{qRITSUa Kxx"  ں3` bxCU5omH7z}OU,mO#Qlo%Vrh'5ԫR n&Q._P%:X7=QPΙ'ඁGQX*%+~qstq%̓GB*ax `ĸ _ꏫ۬aG$axfC=Tez"*Kh6z_WP"*R,2-8#Ko~y֎O6b1f7v%g7Li_q4^Q?Ԗ$uqGԪZ 8bBA.TNgzjoQ$47F0+$B݀v*=~Q|{͍Z^qP\`[ZF%0H C" LM_4ֵQH%P)9vRt+U^x(,nT$'Y'ee(eQB4Y&e5xQђD#|PDSho)7Ϡ*@l+h6 K1هy֖\$ 4nJm@E;k>kI/#=^Dz_S\9:2: Ps(N U93 {C5s7 beNeNkZOS ](:\CUA%='|>j' =O"˹B륞Ig<tnr_@isKqw69 t(Wb:km9yM)F-4jlZ'oͬYڔ# Զo{ 65h'onW|;tx vh,D@>̩3T(`2B8cBC R}S =ƿg\b5eʄ/q躺[qΖxE>X_KFn .TUq0"S8醑Ws7 _hltsiCx?aɭq^ Y|g=YN跧mwl"%Iд=/ lOCPx5dRP[,z>Oi!!CSGSLxI롯@sޔJq6 )p) .p74$ 3#t8 X@iBW71mItZ-Z{✆M#i lYhJ3RK?ds]??ܫі(%E6nIT$s(hl>J mtNADI.Ao~nz(m߫,,rw( 9k endstream endobj 242 0 obj << /Length 2826 /Filter /FlateDecode >> stream xڭYKsW𐪥VC`0xyk7dmor9)DdAd$(RN*wXKI#-n~E؋omqy\^jQwNu )e_6d׵?y XM/mړ]S*L7͔[u חW .w&u_ߤa(4W.𗷛 4Xnݎ C2v U[= Q2Ѡrb C mt]+c2;>aut K2טE+s݈+,†뽰K#ГYS:lu߾=:m$-I(A,Ǿh= شÄEo J A;;S] a)?anv[ H26'vbDjxc%in`]J AD|a] Lf'I.^|q o/ŋ0&EgoQ3 ML]X&)F?.z^.1a1(O^Yzru\ꝍ).,NÂ)1n,8\p"{ԟn7];oXMb}m(fa*LyDkv e\k;M-@SBKd2)s䪓XB$Sٚ9 d vM ժ(P4-F%VէjU!eb4 ڣ6ěxO#76S9iR*-%Ɇ~$w"lj1{s,"Ԭ?!8Dy(s"x{N=ϜQӏ cB ̵&$L˂I&\MH%8Τ ;|"RgNk*jϷA`x`ǯJ㣆e/w2ʴd1_0=Z٭~n{טմHdYsp󈔮cQ~iCN O (ABdHҡLO *$t~{?} j4rRؠPok^%D&L$k1'7߾8?cșyD [TJK&ԫWe)`JSdgzCh.gut)fO*iIа-OQE>ba $|}pOE]dTu'ߗ"tZk_u&@/2a_11uu ;J}s-ۏG}}n_F]?S[\g"tlQV#zoܝc }9Z}2Z:D=-ّfIq) O,28:;gMB/9#|F3^L7>bHy[uUWÓ)/S־Chh `QM Yr?O,o >5%{ߍkrSg[>zqBQ?cIO4#QOC ܐa!`'HhfmSo M&o 8ꀛ&-ۚ{[u.P%R9,hCk=?{*`DO/){"g=O44msߌ PRZ(ZKЬVRoxl endstream endobj 251 0 obj << /Length 1723 /Filter /FlateDecode >> stream xڵXK4ϯ&i'N'A+!b8B=m Nww\NO8Ů*ۛ䛴~ it2jP6Dg%k~7 ƶ7,v촣Ѣ>-I=.un&wDT]nࡄ?(+Zto6e ۫F7༢+) 50Nh0ZU;({$:d jIuf۫b7pLBm@0{^L52tn mY z7?j Aw!p:V7x3[ gdvcrgHۯ|[`ԔWYsͨ'(quCmNأEh1to%fTpb*6dj%{BΈZĄB\7`x--z.{3`qN|Aڕwe&*N@&ᅼƴoq S,po-%g!hR4Bg.)^.-RDwXKt0ؐ+ѵݝ3[9ݺ }`Wqc۩Z;,E8Z.J-Z)e]dTWT>]owpƹO8PqZ&5 ꬡk"U ) p?G 6/ 0EJ[Rv[ rDP= Ů? *!,E0K-4 R3c4j&} =2vrkzCꈭq 9 tMKZ+AuƵ [R5}wqk0zI=fM( f _tHX5 H]K.bdoսEF o>׀!y6QQ0"6 ת+O y! \F?&;^GI[/jLkI:W7=]*^s\:mY[wUA--ET endstream endobj 262 0 obj << /Length 2271 /Filter /FlateDecode >> stream xڭXIoW(â4 Yf g wh-xǦS[SԘ֌džXjm} 0+|E,L`Q˟X(V~ Y|շB`"ID_?/(]maJ *H-g/w?]nrd)?ӏ82? #oe{U+}cp{%w`z&{*aX_*U;~uZ~uZ$~lX#ϰq7w(w+x o7c}xчDzǾ %/3Gg-cI[=fKf멩 Vu~\)yGk*^=Lk0H0=qD+k' u|] i]_f1qpF#J91x&Hv6D`$<3 2?칂(bHuLU䣍,)WV1-v=,E@TC]-:TOL;XkMeaځ ~ Y#dM [0RD\ bA@w$""w"nVWa,r,{ x5R)qs}Fи?6S| '~]4k >4&Jwzy\ԕ'],N#J=R5>M'oEuST y"Nߛכ) )_R_dxEĤu3~Wѹhll1*&3'#E<~ԛ|1HwWښ< .gѽtބupW~ȴdZ>qi~0𠅑b=̲`bJ^uM E0r:;.7dT>OHv_;4HQ`4IO-\,xЧFMPSǟb@B-R؊\IWN-*i`+?c;T7!V6 endstream endobj 267 0 obj << /Length 1962 /Filter /FlateDecode >> stream xڭێ#}tФ˞Ñf C$9Nb}Y{g#ߩr=N/,/鲫\.׽|{(N2"̃(mG6IX>uFiZ_үָSly;co)F~ (oWWp5<":"Xug:V _//[GQPeII(#^^!j/N/mGN.d5{2nUF>cN2#DU^Jr3 75D =A-oJ+lOR~( $,Ql?X?'fkmdZ_Pgμ19 4'>Ғ-ȤQCle>У~2%i;dyrqD,\7"y؆ik՟,|Ѯ$\^WE^gA^A^^K5낤*CzqP@껫oQ(1 Hz=*1 &Z{պ(Q蚼|$^ y4[a֞S8ul'dcNa1(,*FDzPUAj9X=ӛ(yf t]e4;?kZ]/Q?yEn {6IV}@hzA;:ie1QmM< &\B(p] ldTty8HK͆S#A eYH_Vc2_epzs\xt(W݋CdtU8`&=D_4 'V-gY(AfH#Z#ܳtNVJd^ )^Ñw Q=Zj! ,!};HFo6Dz._nv) :cve?;n (*,Ӹ "ye ޾vϭrTBv/k Rm}7GRjsq)^EP^Hz6c;@p%{=AǗAf-8 fK4bꌘ\әScwv\|!8̠Ԕ`*:3݋/_|Wv aCL t^p-PqjWF? V)\(L()I`;qIx=j)=Yޱ aCd󥚺_c+Q8欅29?BJ@62͐]1|t,;(AϾ9PRrS^z")&ʸ]IQ󃿩$iM~Cp a%v8vh}hKyu4H<<|/,cIMsr%{i!> stream xڭXo6޿(L": @~Z%yG+7M7 _ǻ=~wœU:y؏GՈ3/ Q2=F|^!fm'c?uD] EZJݙMM;z_(YUSu dMӏ,?NYXr#%odU꧴rUVf@;se7 C7"RVF7c7fsQUfM`8ٞڢ|}ٙYhx sbPVەThcd)I{WL1'*SGp8 ք4.0k鬖=v^7(`G':J;nkfQӮ\= Q <3/d!?ȏitmVlW#ua4U׼ςHR#:iy%-u;zzM?L{]R279!KiLMNæCJ5!Q+Ƀbg6΂{ml66ZNٶA2=.{/]8oDq[vMLִչFiD˾停A Ȩr-j#(d|3FEgd0W30e0 Ocv2|][hAf#EJ$jl;8lXF48 )D YI2^IomFa bc0@skyS9ѴN*q#t{ eŤgE1Y"G)S V 6b s3anGV\jO ["UՇ@m0aCREH] giinՂzZ04m9num0"g] %) 3/鈗y(PI Bxf“~i d3<%L5di˜k*e^C |yE}6: MJb]76~#_{wq5Eqoy;ƒ0b>7g,̆PM;& X|n4{ ͦϢg\jJ;cz0h1-8;AEcl´pcDb4ihho6P*{{CgZ;%sO 0P*a?Ma!fgg_bO}#Qx!\tÙ \. $U endstream endobj 176 0 obj << /Type /ObjStm /N 100 /First 858 /Length 2048 /Filter /FlateDecode >> stream xZo7~_\rf8$ w@䀻~Pl"$9JJw-5^%}rb 8Bc$X[u ev%LE/wX+(^/E~*5/ TqIX()@:PņFj?9)*6Ǝ:OQLRPAJvb=m\%Zh@RtlJ(,FEԈfl4e1: *Ԕh* MF0~\ɠjT'c x& QL/l'4Xbr3 MR)(z BhJULIX]$RT@hfQtYSl ki`*M A `T"4WoѴblCTk_`S"qY`H9.有3* \[kJ(!*hhlgXaEl˜YBAۑkΧrм{l:4?ף`uM4/FWK`7+ɐ;wggy隿^\};^ Q?!Z=Vg'5 㟿c`DNkb7L.$\`N)W%|1.[/̿ |vrٻ ׼}\m>ތ/n4].̈/ljhaoG: L-}0]8X+BlM@I` xcYZDM 'y΃H}pS7a8*ByUąB?V݃!8X +`"ቔW )zBDT> W&?ǻc ^ Tn¬tx{b~ĭր@I*+Z[R>tBCtƛ`vwo>UZZn_W3]o78: =~jÐ|EBH}>!N\|Hzd"$8_$pxnU=S@݈jNdK(, ~!/׹n,LO4} O*nӑZ|M AMK]j}gHGZ:rn o—0ǾPGaKhkЯH`;or}dUlt3`@@dC#@Q( vpD;=Np_6!)&">Mn4C{JzP8eE݄!QAMclk&J6vɤq!6NH7-N>ʁ09G:ZYNp!8;)OՎ$#{6۝HR}嘵ۅOv,oƁ\|x3])L=8:(LHG˧M|923oּrCYs=;bv>B&VQˢ9o׼l7{\4ףv4j5{wn܌ףms~{;Ϳ+":)LlܟEM3tl}c"NtV~$D>쑏3\rOKX?nKh>Ml~޽iWxzY5L? '׋U&6S;-Y#\C;Nt`vMp:7ӻdcE侮I%fvWshGa G79G"j콑7# ֹRV )^Gxw{z?M ,Ms"WCX^M+\2O#J;Tڏ>9=7I6wml*L ;#A@S̱emo toU[RQl&^lNp>5. endstream endobj 276 0 obj << /Length 1764 /Filter /FlateDecode >> stream xXݏ6 _eʐ8Їv7`P8 G&ɗ;HQv|w -۰")~z2'xμ s0%nx~6[n0_$_ʾEc]/|kķ|[W\r ESڹ:Kr^P[Nem'uMDH[\[KU$ڂSv_4[z!|='"2} Y3_K| bl:I5xSߑH=LY'5J@|,g_W{-}s  b5Cm.$Z<+K!˒roJ=[kZ];0=&KlD Aaōl J t8< ? #< Uqm'>9S9l \ Y ڙȃəd}..}F#֨ݫ/F%aI9~(T^_\/߿AĀt%{;\b]{C˦+7N>[X6h Ўl4n`g_GUZ~(n&Me׼XC74bă>M]1զ!+>=$Bj$]_KS>V蓛1ACA%;H@VVcJ^De YDSɁV<شXh|{T1vP 'G>Y  .Մq3 رN-WQNGk kSWsR(ơ4Z4܍x {ka[$)NgM?MzS`M̓ѼQ&,rr {<\dɒJpڒ-i-S7ġbc$ ) #@ž-lb?S|.2ťu]XOc EhEicnv D\k֤Xv/e:L;3a64t} tp-eLX80 w2oh4avռ4,q[ky2ژb+ H ꗀK> stream xڍV]o0}bc L6JT0#$?CxLJs=\us'*\9AV)_"xrt9!Ev%0q^Rz ݠ>U!x PĈe;QU I=@'H ߛat-w~ bG)WȪ \@z>zĊ@Ϗ=[ˠ;0aX/"G(u9Ď^Ê .BhE4fDݜ<(ԧ 9e hKڐRO +A.tE1zVa5=ڴsw2aϠ 5+@)0Qk qn*m䒙f _ #߇8u1Q[#T)e1_LYJBÚԔbN5D`}KȜxK ،Tv@'%oi7%a~fpQc7Nl{V> stream xڵK0+8Bᕅڪ[P* Xkld;aU{m!b 'f> stream xڕVK8ϯ. <ɦ*S[؛fR) >N[-׭ny?p~E\;4~ĩ3#OY,su2\{(dLo{8? _&oڲƛLUMxuWVJ'Udײ +jNE~ ^3:FZ6bAc<3vTG}q2%4>>&W7>G,-ĘH6mgixԽ&ϞRVZ0k Nc}Э(]hliשֻ|U=~m?sF?,3O?hD m-b'q"7w~,~ qu=oJxhƨCͺRTmJUMGm۶xzECpzO au(p!|v l*紴'T/ʂ#ԯRW-Us"~[S8 qiP! 5xu!{gP@c׌.!n?LⓀCmSJ$1fvq(>Jz}W&]63eb h9-[!S^_5l_Pu#9(qlF!&O^PވUL.2.U k-4%FV\],KL?A[, B5LA<,P{ HyI7~0j wR }-uuo@8ď?co}F F(.c9б9('0M8E.mZrx R4~dza [+w^^ ݦӭ=64i="T8(Y*4ø arcn~_= endstream endobj 311 0 obj << /Length1 1941 /Length2 14831 /Length3 0 /Length 16024 /Filter /FlateDecode >> stream xڍP >kp'k.H\ޚi}WzDYA$` Sfa03123QP[ڂ#9X9Bt}] n6 '/ /33?μq@ `rsprt}G) OwhPZ3mjV W AosatpxXZTA. gw@;ߥ1Q-\R9zAw) xP(92ˀws,, t:9-V <+=ho!IQ+>Sg+GWF+?jd#{%@.pr݋õw273 37G& {+'76"d W333'7yZ2@{ ~>2@~V8; `'d~?g+O}m1$D$.JQQO'z8@yW>3@7 >3qߔu/#I7[?vV^[O(85fW' |{ Edljj׸%clA.V\-f{.S}&TޗSJ؛:e' tvz;)01;ދ;8q&?D!1/b08L .?O鿈b0cLZE<07&A运=,IX7]f/_;7*2+39/;Y-w|_Ss|pdΠ5㝍ÿkq|_?_=ןFbx? 'nm/Ժ1^߃hZ`H+g͹ :.'xHX?:y{3tg$չYᙒs!BXucW'_ =NnHERMCG*ur/ qAe&K8]ahѮ=.&Mc죻UҋKCmrG,OyiJWTz`&.2sh@v|:yoi" '\(Z}*zfqkb+YX]fno&DhKJyQEoqxJ}=w^M蹚ܾW߸@%&4iמل'Πi9']D4XB jęFF=J{=o6R4k͏=PtiwY6ƍ8;oLi6hc 6(uH? TljFmG䪻 LˑP)b>v:M<>Cܚ.5bgyX.'s/KU;nz~{k!pcf2Ic!w>Wv ثd>ۢR?F,IȽXbt@qV8} v>¦xegaUng g}I[~i\C(>J%׻7H1QhhԶbj[MLC|\9'dIס^b}MYQ[]6:4ːkPTW_wv :;[iP7K-A|.-v(#ֱǖ4X/TM$99Yk/DBnAk6DHx},pe7 鞤FᒮXeǫ ;{I'_GϘz(߇N\a؆KCtۄT1Eog?_]lGjJ.X48dBpCȄ3L(^;}]2PT*j6"p0w$7R\ԣ .|"ڀfsD*W(ReR\ Exo3+Qso3 |S!@DtXi_E6|^LvOVFCŃH~Ĥ3 @V2ߒ=t 1A\Sc1K»!Z|; jHOm 쿯:lIjMB6Z-g3.Ri="~cNs\\@$miϗ,VxEh!rdh_6Ij`WѝrcaG4]97D'GFO|45}#HgqlY |= q!q@24u<>OqڪLO]><Ƶܻ 1hFKoc]t>. IƗ6%~G-ҪSgߵQ#|7fTP-lz5J 1i})O gCF]y1\MbFAxeU ,)"^ lRDF+1e*>#5zN{3$:D1tLAeK~:MBɨFANUhļ|J2f9TW7g  }Dt߷uk_VUa7#PxR-ՠ\Z J6퐲,4;ˑl%Ohu^WKՄ(XN<2Rx̙vo Ei`eFY 5c2ף{`/+d;}ݒcrT @N#\tM9FOq<=C8xPDef"ݏ&0;eF#1lCPJEᩔ<׸:~^(-G;[1R6iAzFB| T`XjՕgUj5S_3Ϸ ,#0Hʚ~A Mf\M.<'/,%iN)hG9I "CWʭ kd,1)+6}4Mce? 69FV<9QE X \n>Rt MqZ$6& xתOmؘ2ڦʿVX`? ?bq.X*1@DC8ÂyJ{*~~roʾ6?؋%.]h_VJ2oM 3{2ZۏXs#)yɽ !x~yE7_+4g5^hy:sUV^iO"x!zN8"ðY]d(c%{~YIXN?JT1_t4_6pjÐ'^7uF}_3Ø{J<+M+r,B62CrQ*S*Bu=p< 9C ^oj1rC\NKROy仚QsݫovN2_7z.JH#l4p\\MĐ{,\Gr޴|8;S8.DcBX^}ؑZ k~bSS=WLE5B3{RFoہ/v)?:.mIr?]>//u0D:T5paꓐ yᜈ Ak4 T ɘVdͥUzF4q:ueil䫨u!ޡLӃlzΟBu,Pcǥ* ]9%ߺE3ăs.[?A;|2\/C,G¦}3х&W_4(>LHHFVݐ[%ًւ)j|L og=j:.wtS[{ B!+>&|>QOHGj@#lbŀ2nc {ZŶћDJ+d3S[Uvtߦ\1=fb4"\>2%J5B.>lvbȁƝa5ot^^*jnW3oyvl!) |t]fBwr܊,Ƈj .Ƽ]T'6YVNL)٦,5lCĦF*Q "1u[[ό ї7]OUdXnOo:NR!$䊏Ӓ!>i -LHzv5j؋?t/'L$?,ҮTj\d4SdAsjy+*}nT`*[t6BΩ*;-'.6eà{u<;!HA%VGG#-R>]XYzuy gBp'ODj ]bs!*a2p<`F5Kvif`Fٺf\cT#IUsFe$86^2w8y]q5`sf]/KXZQ>1DΓ d_rsƞLxM^5BSsNYʩLQhw,dNa1^$!?bdI$2WidX%& oK$gԵڂm ~`.&֧,V_vt .mHRFE|Ї> ܰγK#R=~*f93@F>=.+Qr+d(u o4TvuCJ(EA뱴2^x9,}0mN }~!ra*6ωh%pS*vzN[0{*:82y7ZIr\|MZ`'>YfYQ5hfqyJo3/ƯC`3~7H'L.zDZ. 7zڒJ)t,>Ya>~^rq70<?9Ì(b MdKH]Ƴri}Px3O319 ^^T6=O:vʮS.H%/")7oNw)ŗ蚯gYVq~>v PZμ0T1i:2 jha9W+ƽ'Nj7_*8s:2 |3GOfQIH:,G}1x'Fh6Ժr"RW~z( Z0*.x4lI5qd&/X;0G3 4gS9:7m$wЏ_b"hջb@0E`7511:u| k/> B/_9\}崠GkO3wÓޡ$?L|fGIo)46Kp>rG770BnۤX-5ҙDO(*ޡ ZV:,zk9S3ҽrs&fb @M6sZ~BIc`9k ta$K%# .#e Ugp(g.r)~/ HwxflZ~i~htX@s įnf;ˮSITIXت, ĕU d "ߗ\F, j9bvI\[IB ӄṾaөhXg Cˠ_Hň5NyfgCKn;zB䥱ulh' ?OH,L^kJeM#\^~cjf2Q֝.2W}8u[]f,̋ƜVα# T聰zgh,_ Y~7W51{UyĎ1L/#Ӵ%W䭵]bD  o$oցk@ ̯h`yCxU:O'zcVJxk BqV8ƵTt* 0sNn:\;)>~GIcG\t6syVlٗgTxb3_6ֶG488v-'UPyZwWKt4vk( 7I!. a䝗o-2Vu!6KDR+%>I"馕2b΃aB}¥zȌttѣ#A_w,C[ڔM21Zc+p2iƋA:g}5uGCYi+Oxx:䇿Z#}Gۖ;靼)> H\"ʮ\(.4_| 1f|'vF`6-U Hoh j ⲷo,q jϜB4,Q͜v@m)d[JD=HA =۾AR9ΗLӋc[-i,u')s WQ 錬L9CO߿ڱaD;}R_෵45pT۬Stze/d)L')X$E3u&T3WV.eBlqzNmmɂg> r>4zԱv`lpK2Ѭ K'}+ ]Ef~ٱ=zV)LfME fJ|@j\@JFn)*v q8s5Z@9gkdlV}LvLmL"񍤒X 8,J3⢐a>b ػT౷^{nCØ k Ѫ Yt%-a p{d$@by|X?oh]'TNS[OPdОyd[ggtz 5ȘakeY[/9;kC \O=Ek"dԼ^QxϠ$eԗ&Yդp/'o[NɼA[]]0* Y, È/Ū|׼ I5ρ,4YkFL8n 1yh6ݚ pNvV}A }{뮚5h{rP')tհ]J yJlc?~Mktx6'52g/T2*ƻ",>2[ɮ1c'(}$'soF|S#Wm#wj&q~1gC{)q7}j2F;1&{\]V mGB^e|O 5,^:1h7mbғ2U RA"Y )7/H{XJ l9h{`iM?p7A(6U^A.`Ohz[a^٧hd[Ҵz ȤpvRuZ8EO'AVkldE9ID `ĵ[锕uZ9QwX2 ^V!J5"oF#mԢ.gdd\ׂLAģBU5{[?kl @I0%4sd] e'O[v!xB(qƱ)ΘkqRb[|u akdq{fr'1%PMd Ru?ȋF X+h#rNxe 9$1cT5v{ayo0\; w]2,%cDr=N(8|iXrq־'kWnU\U>Fs}XOFDݦrR2w JYs?ʭɖ>O܄C؆bN|d(azȬA9tIHmX ؽaD]/(U׺5&7T!ڰ+7Z)5l jvU^_СpS`AhDfF1;x|C|O㣋D!yV`t̺@C89 J롗ߴ+NNNNp QEjmxC YLwW/Q)_\ikz۷н(JO*u2>}6֔m/<EӐ y=T-ݸCBlV#L^`ieyվ61GKf!'\š:DgpI|SߎpP޴Q~7:x 2.RY/|R6ʦQ]Ăt#7 甒; @>zJYhW; S-V}iQ=uHC(˻+:]~!p`qE ב`0[p&7ݏW:y5rJh]:lsefhЅ5CY{; q ٖQNMt} ;BL&w=\_d_ 7idA$ f^gH8(MBHU ` scC݇8g\k?V%-| Lt#< ?ՏGqKIeVN+G0iL\J`3IL$ILQ̿CfUlXL /4x%d$rTQFzzk ʙ8<}@^ 4\Xxm{KzҚΒa, }?2j2gQ>Rq re$ L̵musAςe=7̝lIeniu 2L Pxb B\2OVJ bʢM [V>3UL $պ7dIx|H^XtRԥ]]GW?}'q{-l=`buLu2ߊ&Cp8m;s &'3zjqM8Tw'?39~g3su@d#W-YĤ[=*z6XND~4bZ>kWګaC-dUO(7N%V]WQ0wuUuBϱJj^_ `e,V*V'# lL]i꾉XQv$FJ͔:ͿS aݦ:bB#F?iVGM.Dۚ&v6[ĐlM@ALD'h?6h-b.Ch+Og ÓVfwU@;4S>bRCUL2r"u[bdwkU}*w’`NN?upRDY|&lOi\_,Ze:6 ZqqihEϊuF(Xy!`╚C U`$% x?a !AYWq5/X1BWH>qhci|q Ad-K^f1h49Sm0S6YBg/TM-29-ǼVϖl8JEyKTfMr&zv?XM,#<6!Ji m2q,5GŠƸ5qd2bOj1ԵkAWpGmbkvp-*XE..`!@bGI)j(Qxkяg9-a{+PwL1 SqSܔ|hvAFDjw~kY6~_~<.,sm}2ES=3 -&+Cӡ=Gxv oT!@UPM_$q3$^9E'?rɊ$W+loS{60#J4D9)(15&JqBdC efy/v 8QώHGݫ9sv>-{$D>v9z?ty(.X{Ľ~r g͸t&zlA"e,CΧpgݩŜgiǼIǷ| 4bJ}1z5`'dfϘS;}+ SEZ\Í>i8wv" ǔ+]Mf8O &x:g>)+JJb!:F=h;~Fif>B|yx-sU%:[}9!C\Dxczzv fjZvW7")BVm2RRu18+qFI[<`h+S_kyvS$ǨY_o* LCpV'{@nzhe#==_.)-h]?k`3CV!0guEi2u8d>u|аNJ Wq-4oڀ>Cҷܒ.$8RxZcz ,O4%N25jhcp}*Qepg BZ^=1~cg|gڠTZȍmob=Yy:f ?塟 W=sΝlwl3)D4yv ~]E,2W[rJ NԉוJɀ:H 0M1cQ$6oRPP!t@6F|8_G0]5!`)aHTtZip8}[~ۥPl'xHvJbUFP37yA ѴXvL₁Oe+=Ju%g(xCvlzhXc -kiHS>S5zRTQL;z ,1: ~n-X춲\ >dBQf/Rxx9:GM>3 `dCM8qpXՐD." Eocn,ket'+Zo Q['nXa4,|)o*C}@/'H endstream endobj 313 0 obj << /Length1 2243 /Length2 16249 /Length3 0 /Length 17571 /Filter /FlateDecode >> stream xڌP !3Xpwkp6C +9anYzw!#S0Z[921p t LddJÒM!ds8spH8Zl\\ &8ZqL t k+=,( (4,vzVi=@?)(Ml靝,y)iΦ&= hK2@Foitd%S쀀 SG!P,/`coG`=kK=+WS+c +*E@г2Q#^IBOgo`gj`OgojF|YPh`W}¦v@rͭL ahClej3c] L"PrmdC C^ psz`hjZq 4;S17 3pˉ P[.wZVf-+#ɿM_J+kÿ gg 1JLwƏu4=z:+k8O_7 _ @/  /bgЋAz? @bЋA.}AEr"}A|E,Y>7??GCQ2tG֎vp1O}]5q1xx|~5Pk!d'GlG?ch[iۇ-?)/tBw7<e[ٛ#;xLhNg|p?PG?Gz?|g'c] _jpi'xfU(iݗ?%PVm $ P4} no}xщUo];LJU?xP5o ˲u@A}ps/Y Zؗ?d{)T-#O"rŇBpAEɜ|'ɜ﮾8^d߅M~26](Qsѽ Z"(_{Iϖsdtr{뗎P tP/ ,Z™WF\X{W 4;sS98 [ >E%윁~Nwo%&lnw=0KI1+ 識JS x$z#&D_tO3T*PyAq#$ƪ7%:{e2N Vm K4Q)f\Va$L9U?NQʤAj+Csqo &ꦋgB~V yLL~vF( 32vҍM]wJa-Vs')aK& â.DH'ImT73NR~s|܅}#VʧP<98jib9'wel],$x_jZЩyW&jNng(JnRѤ8jofHxb9[n.\kvhMj|n[3۾<VBąq.-%NX?Kp(RPչؖRX%WRjAg^>g3Rvy}/ZD6D(fW}\R}oNUBOTWOŷ0״  Jq ͠j$j+>~Zޅ 4b|gQ? }OW"P' M ΔR x)bkgqZ0KF e=mnKau9DJl/%ٓZF2G_ޖ&3s>ha<#'/>q2:#-N*vARo^"H%x @B8ݛMͯ!ST-Pڨ8xX5IM6 /YP8wz{d6 @ʷv@?!g@ շHOG>$htEsaXM sK*43-15K-F>Ls^I_JM$BgV >DnpaEIpbLMxtiqΆn=xAzϲl uuIVQ:NȊ jMK B< g6slԨK_Nb(xLFȄ]ɀg3u ID(z*^`o#rF"xEǼ]/HoTAZDi#IZQ{V+#(] ^#(6eM7$}aݩnOI1{d,a^:, *&#IN89{ A4-& @]8nߛ.ٺ5ߣ3fPw?tgEoKmvF7b/ $N'(1$꼬˥qԞi8! \OvWE]r*.cit\ Tn3m,'=Hl :%#F7 2Ճ f=}O)0$d+|w2su1uv;̈+Gxf%s o~?(;a, oX5Hc<(I@ipA9MDa[Vx xVl zLD92c(r$]nxsޘtܿFKu~*ʄ_M# "3ŧȵu%QkFzL-]~a5fp,mvc{=Ń2oia9 WRW/+RYx;I*ZBl٪f*mt,RY;}^7u*@h< 3J׮ {% nuO.+p°c>f~N}Xg ܽf<O8_ }=gw522{]k.`î8 6SKu gF“2$Ġuƶʶo){z-N3g\I^ SzFσG6R5ZQ+\WzL-y|ӨkkYb 5\eOzGb-3*aF7۲:NAuϢhn^`@y*yo[/6;;"Vt=N ذc"@kڨuKlcµP/r0rOO,i-`},sÈEL{ҳ4Igl:&K)cf3onpAa {a f0E^nR 3&\n2Rxf}?Ac(g$П $0(x8wo8uhCCvP /E2B,8A1;ղ~8!zy6ّe/jG[_kur:ݿr~,A&cKݼwkiEi&m%b$o W _ Q^'A&(=]9 W/OSG=|Qμ˝[n'>)~.BoжUUJ6'G Rq c<3*H`BGqzb8.8CLO=lη"SW'<ѽYHā. h w_o"{o6O9FauȌ Zcw$UJO܂@rGd҃rhS3SC0 ކmܠ.Hjz i/4p{ڃ,4UtTUV)_|=*4>_ Ф9{7MIew#a{v+4Hjl8I>>.)Hn7Kp#qeEODq[x݇l%ǜI<\{L0cXN.Q|NXTr^\u[[*]P,43D6+e bZHo袸MZ) IR'ID,?v~=*b*Ey_; c!buctm#{cUݥxHTeSyh>MFK@Ƥ-;<).'BQ.|vh/5j=>0 C:"*_MU=**ܓRӧ52aU d WC8j_LCbd;T'Wb@*O_2Y3F:˼tƺw8lbC' /Cjg1hQj" i@UVL bTW(S8Qu2 y(m u^/"\9<_)xEՍ ^+FŦ.3n&,r9B.mw]ĕЕ:n-nt1@G7 U`~zTD#`N6Ȥʹfy TDBW~v5,xpO QTZ%n%Hv<v} %kչ;bc=*D7#0L?aL85(ւrbױiim+wD JQ޼i >?H~R\D WV̋Zo]/i1|dݎĤir'ת} Nҋ{m%iUORc4QC9(TY[D#mè.T3:(#閯Tl/;=3bͷRxlD5d6[4)V6R^#bl5K>@JאO2a #Dz[!L$J\/B%l]S/rvOУJo39SdMI 9\zZ~i$N[|KJՏS\%]-D~mЛܖ_{i͖mS'̙ԲLpE7ɋ7'ZhϡIHR)M>qz{P}j-vC+ gxvDrP9d]fr(pƞ)SƋQ [Pkbc+S_K:'vQ`^S#d(0j8Y<v< :Ct^T2\Hz?*w*K(R~jmhʯP<4a[jQ;v؈ ,njɺOߊ`:яBL?`PWrd_97/Hi8jYILئz+!XE~{{xB@)Fտ`Nh+Nj=I4I֚P>0T?EM4"'q&AkV!!~V.^F SSI\dD MB@_T[v1baWd;Lx筩CkRdO_dX%pwA[*;>nz 6&L$NzUr6SG*B$*LC3|R(vHe ໤ s*Q0֢FuGbٶ=ɽ*L1^r>y>\;Յގ"a],@m\rZy8n6G P|L8ӋO+63鵃F|:ҘuqKYjڣ-4?G3lTc\Yף8Rpr6C45jNĨ:s|شۦ4K|ZN7hlS7X3xoч OTزGQe@,wyxW^RYq!5o1'bJhS|GNֱaQXp(giq煇0nбio4:yQ{^L{EJ՗%/f/Ŗ2,!7bFdv'2hT *򇃜+Ǟٕn$G].Xq]yHl~oh!d빇+r4U2&[ ~|ЕZ5>X-@/ =sޮHCdknxR V*i)ɔ쉪9UsnmIXBj.UKfiY6hF"t$, Iٜ 8֒rHaoc^0$R>BX ڤŝ)Znme `W{Ժ,!nX7Llo2DFuKTF!W\ny] [yD`wR=W-lMr \oRB6#G| DZFNUȑq\}DȌ}kJD֨ي]T `FK# Q͵*q|4{G5T=10$:۴4i^2~Ͽ@X(3~lZ3Avג^t& A gZijy@Y?rW*@ q-wVЦZsW}"ȱp=Dfjju`V!X6pF-Alw1!IuQ <@>[Vx%Ăq9h>Ntc! hƓ[뉹/wˤPǑ#wU}ۓ4\׻eqK"r) 9uqu6A&atWRXz;*yAU\X5oQߺͻ?KtsP!ktQ`9sNɺOCa40}{pGe#`ƈb"5lVh^]Cs\T;q+ca\WYڊ|inZb->`i'W~}ntMmyjPtLh= WPC^# Il>'X-Fqkuf-ReNX>ٍF(@awp [ lͷH4/퇊:Y Ֆ^0&q>,V,3ȐyMImo9qW j!$YY+-H&44O Ƽ.P0N8X~_.fݛ.dl+K`v*90F3jNz!S6>&s߲f-5ICO'W$)kGV`V^N$о*߅@V6!Jrfm+&8.d \:d>Iia mcRU3:@wyF$k;?VB(.E(d@ \WL/bs:آprؤ"CnMv&΢BRBm=%)Id(&äcq9iXW;MF0@-$?=ħOSqtr!UUDȴjeKsoɅv{Wz[wwAk-ת$:Wܰa a%UuHȯ" cH[͞^b̧/wǹog܍;AM]緤ګqp0N>bΔcFT#ODlVk_uJhT}i/ә! m蝝xA98\;EQՍD}ҕYB_pe Rp=T>\:QØXXZK̗Gd-Q605zxxeWUָԝF 7x5'ɴOd7hy[I~Z_ŠCG!(`D~)Դ KO<T̅S=&JzSAб|O )GBx/ A0~fɜ >%ná?[g{AT$m^~4$϶q L]pzks%t\*'Nkuwn\-Aj^ k|9(;>K9מG,jNu\ uJYw" TcO:rEbkD<fo>F FERv)V+*96K<i& *nołJ,\>KEnzF_9a[W4RO}saS6]#䣃gtFX2$Ѫ—޾.C}|8PhUiVK\,TTP$ 8:{\ԩEaHl"Ҡd0>A8_MtL 4F*;qrh:#Jho -DɀcLŅ *wiX$kT\g**(YД7bj2⛏a- >eAEsu,fAҟaT)n*x"!(0RES!*TT:YH_ػW#ע?/*zA }o.pdwLI muQ 2w-d8|g5G91,ft-# BlaӒC;iDEFZ]ؔڰC8wjB nKHbR#a3$)7l|h G j;f"zC֣ad ~Ư.͙$!Ed]RLOTj }bV`*v%" ";?Z@(< \oKW5mBeIlZ]Q+ !(uېpu>)Ʉ_t{=̻эH=']Bk5A Zϼ8?ń|6sӦȍL;%(5 ؾz+n:;zG:v ]K`%W`GY^b3# !4O q9_ԥhk ;$0OH#HЍlx0g0dBŘydu8;lqDR3Yu-R=WNk3t/Ӑ>'a@c:P^gPep2ezXpl= e7ߟ7j9A~.a^V9 taIAY͓2~,&XO,: |EtDsWF[ڦM%|fIBQ9uυ%79Xo c/[^qbK&UI կ~d>YUurrbMP r|E{eTjK{Ja*OOȎO&q L.zY\w^oT3d"h^o%է)3y[C3T! 1Cۅ.yxόCuqaEa?AhJuiuMHLL1doc 3\H.x_,ZcG1yfG1^̤nuEfO;^UKKR›N2+rGHU [)q`Pǿ ZjF%G6cxm4p`#1 ;x㏌VMN0}\gE/!ZFN0>69 Rĵ|@m%拥DaIRVLO~NQů z]CV~^TϕE_J'a1+vߎmN*N:ĹhjLcrB ^,\HT|mH UEzWFDPP"oմR'$Gmau_)mp5T$܏~27T6$gde6l0^vOԾ\3^8$IX1@IV+P3[JD!ޣ:b6)EFbRRƒC'E͕4t2y^g +) Qy[Tpluo؂xV&f\42}0n"?/6bl;!U3% 3h} Xߍy^ qTݙ.~fM\iTltS@qItbJ'ZzC45CRĪ3dvz c4I0c4cq.`B{уڀ6Lq/ZI4R_[!u6q9MB pPVY~AhRmĒx?RG`!. %B}y6r֗;,oawRH C۬s71-uDָ5YQdz $;CÏ1|x:] 5QύʺC_7@ޱ8y.2{pdcCi𨭟vj6ka>}*C8Rcvu9P(->A-g̍vDTM3[F圈m©7 dE>.|}m%#"+Ҁ;%%>~J8v-o<=pd\u(G6?S}rdž' )7-DOb_Gh`|ujE"pc}ur*Sx݄3 ,X`zkc W 7@#O?K=Nf Ya4]k Z0g>]vHꡍw QxC= J8,[8 a{ {˛ޙ! n9ȍ){6};wP81ˇ'^qR9M-M6=J*(iO˖@g|U’pmZ_=͠VK5M}^+0\o(`fC/DzftnhZbc]$:>>J/ \z#k(bkY>]s%{KQh 4*p"e˱?#m-ddhҶ[M: 5|rB\Eź.2jDnX4||g7͜jqZ=z[ )vݡQAk H◷}W$tYTLȠx #&ţ+HOzs-FSj݈fhP:PJ s> stream xڍP.Lq/!w $ w-R(^Bqiq-ŭX@q{s9{d3a㒵Z8/7P !g$@>L&&}0sC!b22+Ppxxŀ@(C(L ` hpT;&<w?j m +13@j}+*m Kqp.~7 дr7&@\jg z*-WOc? 8wCpZA|{RR{9V߆VG+O+[duV ՞ wv;nw)+Bl.. w} `q><ެ ؁!vp1<@* <0كA (,$@6? qQ2V12urrPo(O?;2@?}*-ciBY Cr3 1w %g?Ԭ?j+_?.q kAmWz\YC+A`ß\Sn{ǜ6Qp{\,LJ@{)!6P '(|0 x7<(\ }Bߢ?0$xlF:c_ x<Uq{xCG q%}>& x>q#xؑ A6_g6⡎u5^\[SL[3ظ>z\㢽fy;}=ԍz&@{-5EEV8IXѾl}5̶aR˓NU<7\K^eo_gt԰n' b͂K̐ѣ¹ ~z?>;"{UM 8/3Y勿]z܄N*_YIԇg>Gm'[㵶R.yeԸs?&Rn!+HiHi3ͱl_C?h0uid~qe֌^@aOb֣يfil .ؓ0_bG^SgFsZ4Ug  ن˄ʿ2bPgzrIŗ :o_׍`L+Hq┿<7}E>7@z90r<|\Z#R>f5k戅8 yj-п0RGׂ?E W~0c:L3CFU]9"aZn&ڸNMCs_l.Clʒ!c[{hLa ;T\,WeH'Kq;gScZ dw?ͳǮZF؁111pAjD[JU,^UU#JАOjpv麆evY:`UYt'|3j@5A >O-pR&?"@Bn*PdG)J$yl?W7mC S_ ;bWln!\J"`7s/,O]GCā^#= b)̶Zy}LIAn;)`I".!L':E+V-uD*s 7jw~z{3 ՓݜZˋ1''2?[+\9}&R:ċ+1EKَsƇht'J~cwVEA8IZP:A3AӱTDXAdOPi;lk([ &GnC %W JT_Ef%_N6q{H}BFI/u?2Lc͞`2Wܿzw6 RwT&gBs`2f ڋF0]f)qqD"~28yk  c(e E%deY6+d$Fu =khAT[}@ʎ9U3&Ȭ-aNl|{}佽0m@uow"@J|I:5WַF)no^v!.)j힅)o.u|fwN&OS78DMy_'؟}/%3PHwwYӷFAC Z>N#rI\\)z-L{/8A,9/\ƕZ$38d՗]&kR E_G:`%o$m _ Zí SF7JYxJ%?gN6fd)"X 6@^W 6 f>U48 K1WU]CLY[%gm3anTҙw;"l+7U5oƐH?۲,朲y4ݫ5I+G_Ma ռZGqj_ -7\d1sՉ]EG)[6h4C%e!8dpdEWy|w& Ο0T}Y^I.ƌ'tFV/&Nmo6UV}Ͻ?t>0gQk1uڑ3&R&G<^Q &]$1n7e R[DZ%ߪC$n{`A1cUͥ[ HL=f *l=zU Q|׎ͱ@eBdUM|dn\VYWtt8 vO5SqVKH97l%f?(ajb;|.>B~H1XpZ啎 Ù{j~Bok<%.+e Ť]Qz^B"|Os6#V)+2q9N1<4r*Qך"/HIẃ#wҚ݉H'23 tqB:%ԃVTWudwje]"n4$`a6\x00EIXz7.~]\g7~'HYÊc>RMDwzLwlPԬsf!V$!&F~Gr'EUƅ*zo3&!>6uTW=c;?4Ǒ}jƺ4Bk]sHC  a?KR)JS=1Fc¦ u,6VkƾTIek2K"JEKy8/f=>%R]Kn@ǚuQ5|/2b#xwx9G>2[ Q im]?X9{FJ A"H `}*o賸cw/p ïJoTS<~nħ$h,C!P Y׸? J;għ08JW]k"7eд ǹ_% <"T5J\LFz`;3.G SG0{,x&ZY^\r1Sٗx׷_)sYYb+(R%5esj[ dH.^_/zВ#ݍG}HLu^ó1 y%l~vCW`W׊k(_Pteq&&~ Gp.{C:Jrߡ&͖uMEhFѐ"NM.dks'0/D?-n7! Z'Wow%pnؓ@T6tзrg2jGig%NF*0|hž6'~d/hbhʶs_xDI+o},f==4!f&p:ؕw |t f$By:ho,ȖPv9+VjKMt0oREvk)dŀ“:\Rz+smpG)._nI`pHș-6S;81mZMm Eb\Hz!bo~PIC= ja"Qόg7YIl@-S#bcyȒ62S,֕0BiV=b޴Pln<0L 1Ϳ\صrp ;Jpd[g\UC_Zh"c\{ eEThޱ7?Eo{ mqx7g$PEf29a5D-<'Om|Pő_^BDZH%|lC~c_2F^w9,Ƭ"!dr׏a9: /'2:W-!B maEPU1)3/] 7iJ"^"~ZS7n:'"ܐWAfo5vtܚ C9Oml͗ks!W|RiJ B[5i#CW"q)#fE2C;<6tS,(Oxƙ"s,m5:DUzR`M8򐮑11,K!+ƾT/}JzmtqB0Jo`n4>KFlրU䣔wVWho=:Ma+,dmo}tN$s8Kv >hO-ŏ۷!sf7 W"Lb‚[C)P0r]0S`ч9evހKZ{Sijq;V5QhRK:۽ ;f s O:#cJ"!Tc $8M1Aek{QrjѴS[.i!:5g](~lzS9\m-U+9QP;{Ճ,ub-4owl$m&G"@U󥕰o *;СQ~0̚Z|+xdCXAC:{E|4/K]U}kFh,M)$M-4^9HHގ.lt/ DR{ؽ-QvI/[&#]^;i;#\Bo"눲\zjzۧ؃-.Arc%o\J=u6D=sn"Ҩu-㘹8&0s+OptED?5 @`{H:$W ӱՎifitSǦiUUQ bøey_1?ONzg2+#Iŵ#LR~czVS9 av!(C2xfr h.,]=t'v?8{-n(̄SaFTצn0nL!FG2kqɱI6u&ʃ0;G&yG9^GTkU $F/H&s8M[\mNp;r?n7~#z}2;Lv:PmssWTd`aWFH=$^IL/ Wr f" ~RUYk au>;e $7Y5LTj[2=LH\(=N_hDqX\8ۮ@4&'QFR5#o ѐ4?_`ͼʕ-kqPǽ T+K~%puii\l|Kr!#X|&ĺmU,|̼}0'jXL)&za"Y*~r#.(uc"VU]9KDĠS ʼj6 4BAwA#[Af ôR|٩a1̉jmG߈PEjvٌ)b JZ -LlrM7Ç[ΐ"#C:Pe"۷>O x0Kdx]«/Fc_FH@_"Pl,Y`16 mt{rթ/ Pa!MFAY|(,'o$/dP;!$V8xAїKIbYHKcU*?nɘoP ԙM'.reudک? ~ 4}r06|H5WD x/="ִ.*BghlH'WnSS:om0ڍ\+*zŐ3I?:xG"eeiY=1Ku'3I*oxV54jMlY;j+/-*t4navfAˆKu\Rv~ Y-F3,q^oK>L2X`/`:E#U?9'j'tDUJj5y:719`Wls)t,D o/2>J[$Eq 0npGJnlM ,(]\s"~ʅid#}~h7Ȳ%t x绡~g? ̙dhATgw'u*N I:!J-Ӷg2\!5R­Io :H)( ׸QϝϲUdd4is3]~$͞ U;B~S \v0syZ(ܚ;a^U=Φf\!uytVOviyQh&`Df3@\ȹy},1BB l^1%G/WL.{ z!N”zek[E=Uht-`OԽiJ96!Nrb#|zӿk`|ic*_0yVQG¾2[Km~_6?RӰmRX)kD盛 ESu5+9ւ`'MM❶Xʛv [9zQx KӳJ2|%r1}+OX+L^$^Hc`< a9a^ATi!ASn{db`;p VMG ;Ԧ tK1"Ekjg+$C}! w{Ϻ eK)IO4E}1+7MYM|ݿ s!2Yq[ɽi͍ 9 px'6Xv#%F6 B1L]_P٭JFXu %2Ҽe8т\-jfi#-A؛ee/222:]X'Ph=U$9"̱jTٴГ/xfq ]0b }RQ@Z3+QD\-(ܫ?sG endstream endobj 317 0 obj << /Length1 2690 /Length2 23501 /Length3 0 /Length 25010 /Filter /FlateDecode >> stream xڌP\ -.4ni$;ݝw 33wWWT542PƉ ,```c``##Sp##S:8Zpa 4tD @v6)g+#3?\C ,@G&lk`afJ?_TFNNƆ6YC's5(@ px da󗳡 srs01ehhh 7t124U!@LP`j,-~H+ hʢ6&¶@'G_X8Acw{66S _M8ѫX;%E1~̀NVvNft36^ԁh898=T12L,F@3 Ab| 76{_~_єRѤuBBnOZ-+A_F21p]-hLS?8%g b-@: Ơg_Qo$9[YKQZ[Xc"dmAg`MՁ,k% A hcf-,܀& No+*:ZzhA_:i[ J.)EmmM~+dbx2nt6N =oܯFlz߈@/qE~#N迈@/1#&o XRToE7"jqjQ@ٕ~#Pv]7eW@~#Pv]7eq, E,솎 6Y8Z6Fa9[ASrп P>+(>d%]/^ћA)#:'#(#cgšY~A?"o @f@Pߵgng$#?я@Ц,AZAS5Gfڀ_3(ѯA1mb5jP;?<`aG_ =[%/?iY~+ŌvA#p=!#detcG ݿm&h1:w2w_؜\mppU)An@Px? h\E:?OacgІzO_z@711wǺֻAkۗőmŝj6iQ:~SdyFYhaܐo&r~JyE1yj1EO{,W09vhÇF Kž,)ZsSD!en)B)¦edq+7 H׏P[ڈ@,YݢTl k7ZnQ2~WoScp?mpJPfz1{3WFjQsE 7eN@I  .IOo x<υp7 8􀏼?a:l8k_BrE x `{5H9;+1g5  [P6LџUbщoΝHlV ,;QTme-P$:k 1۸)/ܷU?t ^Wa kWtO|9kDr"Bd9CEѼl>O׼HQNVu/S]%B&r4Y"$~P ]>XMV:,Mn4H8rMU^UWSգ(!m |cGR"יY1MU:u+QEiFmLS` $++0rբR "I!Wӽr*#de#Sd:6D-ٽW6Z[ClBy<,0sį$iȲ}Zڐ?">AâYݗwKUԄbԅ{QB-).Z|;[)>UBj*jk,kSȢkuN_{LC-{J1QE% 8!e7yCS3yl`'.-Pv&V_WbUeGuS&g_lk :Ff7sl֯RkOM{.u4t JN>{C+G AQOpYڃ؝Jcj\_YUWւʨe:,5#>r {"@qIt G\ʂB28ѨgeEe.r"윤2/ sfx6Vl!R1b <Ұۇ т]>'mܞS_ g`[Zt5(asu(\Y`'N@y5TZx"}g^dn8gN MsCNoUjti/}ҷd}_JAFF%gKgyK><'l[Ws RQgq~L^ܯP'uI<|ޥ۹\t!fǥ9qb4i W 3>:ܖp[ʅLEH׀NrtL%X=PBE]^[/2y~<DyZn ه^A<QX Hm?|m S1aLVwc5iYl3s,V#g8f%Â=\bѠ@b#iBr9+Z)zrPM$AJaP& ~OlkX]<ӳ0Z9:6.ЅY4,Tq*ԼϒpŘJ Z1 Fk:v6H3}HX0NףSl5# 3GTR 걩 r(&d+to>{tC_iL<, Z#^1H<9!W;X5ZbxyI4ݼs9rd#%nvM'A726)oW0|c jƏKBV؀_:q?MRuͺo(~Ck J[QJafEE{ҁDKog(YC8e`sZjQsAޛӏ?hwB;-^'m)h,Iye+>AqstsI DM\f.#fK}S}} ydrAGH--=#gOvN#lk(lЫ:pXMDj+Y{X!|_ePpp3DjA|7pVI8F$][H|\Hx4N%N?۫bx*E"IS4!%WG#E&'|y'j+~8n5ߠ[6Nst}!YmQwŸQ>ȑP[)vI^HL^vp ̉bʽ¿UZf婠j1_Skc1&&hH7EJO-AP-&Qqa[xM(73֟:p_眎_^4Y b|3ܺ U"(4BUgP$uwn!?sRK2xcM6{aœ2.x9oeB]+ SƆr ?e>RUǴZ3HRz 3|Qf-"7x8iHqMJ/mօWwAt2zxiٴukq i̙2#{Awj8џ!Y9Q3"A >GJll&\Sb` j{(E~cZc%!eVເ/Qe=3_T[J`)Iw{T AzrD=EŃ- C¨wo6eK^c,@bvqmᳺ<[Iz%lʞn4|Ւp#7LP e&.D&<!嘄$=(wt`\OVΫ-ۻ{>9wpF fEm߭#HX䈰_r,r^^.Na$,$Uաe3BQ'R- ~{ɑ%>柝4LL O.@'El |l*5RTPplLB=)WX 5qrE:@J'׺$x. o#+|c =Ҝx{sU:,$dwwM! 1IGVHrs,*Ƅ:S/*7D#k`D1 bz.úK̀ 9ӢX-t+ϜF;RE~<C.V@e5c5^V%:fWMMN}vG/]xUz>F`[d[o.̒Cųy>Wsb2v8͢z&LC#4rxvMܻUETU@:v~%i@.5`-t곫2:_vr &љ d(&;?}-N̛ \]-=&fh-Bf#vo);RS #'ʔ Lf.>)1 4ű<!qʳ֍M#jnwn|B34\ucIuw@gX]-$G9[6lѶ<.>e$jed_Z?wQSFA7F]b{Y0U|NdP%I([ C^vMd,yOnv^=Ҋ8Bvf768z mʽMz* k3CKף? E|ux.kSGő}"M*T!{UMFjs/r]'']?zzϬhu ۾e7D;.o>C0q]32Ƿ8?%-ڃ{KuNTN۫0ʈ߾P@@.lɢo;LA8r}g1+:0q)7ݙ|$R^K*?wAZ pލKV7.8iHV`Si:dSאBľԜQ >|63X$CԽQ ɝ/lWeǯU(|yaP8ե*卆9 3̌,pɉ;&fEq*Qk"q;V$7Ĕѝ21zL_#p%NtCh2+c q2ԧ v[hz¡~e.ȷ"o ? Ny5Qf٦ӥ˚&d6݃eA'A>6lADBPf c"ɆXq1*3TMcK)%oMtC`n61)m#2Zh^`W R \˧opSDHzބ Pр]9+ؼj㒡\ap}]Uz,<@ք;o>[ `zz8c U Rmw2 Q#`xgy??yb ٹ Q`&fiIlNj?-eݏjۤiny{B hJ*A(Q1c佲E4OP6}O[l+ $ȴLPZ6)*3IKŪżԣPX!{@ڎ꺡嶣Ѩrn ӃXӁ-9ruڝaZkk1K8Z1r}ȝ~5lҝW+Bb\r-{(*M#*5N<(g٨Zf\uP0x @`{Iֲ!BYBr3n/vbZ;%!ؙ+͹S$MwY`y ?"mŒm5~wă3vhSzh!"b.|v*7!8cH_K00 gR6KԖ]Ds^!sj(xwWGmi%_g!S܋wF΅YX_qy&]e҈_r\uJ!ltð]`=0q vRʾe*9)ó둒 &wm^S]w"THRMzژ8.4sdl8)#"Ik.":{p)a-qMSybygђjXVsPפss7sGeGZb{Q]d rCyM;uȋr-B0@hw`ޔqŎP&̫e˜yb/Rg3?s >dL+* w's9&Lr^fr-1޸2.uHa`N`y}ekWp>KGf}!*b*H$m԰LfnJOZ!Q#~׏}RWs"K.'|펢uEVTK*3~HDnUFI/-t@ wIg3JJ~EqdBJ#+ϓ.T#WuWYrO e$ca6l/ W~*N:[}TM^δW\G͙O+}n2[ur3<񹇊NofECD= Hkfs Hݳ6OзIsi,ΚOٞq=zug ?BNJ Chz D8kA!U~>'<hv>ߡ^ݣI1v54y!FP|Jjq8Cszگڷ%&h.ʳMP>:, WpaA8^NlLLՈƕ_ΙJ%VE :ɰUoX0T 1^ 5P8sATd]z BH^J/\iͻS򿃭7Vڙ>FCds< F4ι[kȭr3稷e cDm;c61tV)b}. lDm u%eC)@s f5-ma#U.{^ᄧ8W=|qQB8χfHx2FǪ}"S '-\U>6K87ng}lo 8#SCzK'# cƩFh, b=Y3_®:d nF&čɉIPCy_}'^zѕ Φ}cohuޜU]85Ǘ+d9د߅١D\Z`vűwWi#9P8г'J2uP<6bulEwgkpʍjhcAsa7KOAz9|k\1Ϯ(2YIgMcf< e$*x{|LLڶmsN[*AL8_C+a.'.0nKK柾 BЅP&tR>ɺp0Qxsso^iXG'WEh@R7#18T PasI)QiV]oywF᫘l%%lcЍQ>4+3`vBX8yoZsFS(i4K>W41n~CMM!q>y梞GGxwZ' JEA.\7X, ܙl^a H"0 @5VH?~DB<s~MwA߭2ye?K9p=0c:=+˝?.\rPFBvǏ`x}KMJR"K'ᜏ3y(pJ+2_qiQoΠ}΃*/`#LqC+&dm;(F kFg{+p6(E6Ukac40L۩OmY֐&].zB3 = c]%ڔSaX( gaH;oB_t*vs+8Re}dPզI~ӋK玧 m=PQgxqsvP51ըC _> Xb !ZY,CPDpVfRj g 4XB$YAX''V?ù ͚JV}F5nfy o h6?@36 0Թ )Qd_| aQ#?G҂cW̋sB\f"QsY_ҢşD&fA\7w|1J VZ/e93ԷdKHC:;ku5=[EӀݲkѾoS(#rnH;WB&O1DS Ek4P,^i&I]#8#y*GoNyMwKX!~3%Sr%v ǵA; a~ME|]e<<=>e(h[-F},`BVF ܁y":t6l,]UK?K]{G>ŀ'uCᑞd2 > -~ Oatk{(7Xu-{ %&+.9 b.1V"ye/u[ru SN jp)kwL1u/àtZۻ)VJ ppGBjy|M1eqd&7^3; KٍbizO1Bƿ>ԩhbf2#bsMEdOpB/_ZtTOFM_sc_ӵ-f|4hOO~DzJvd>` wIaU>f!}wGƩ#~ x i=ksxG?((0yɿ#J'9VVf5EM83OL3 i!w:IxOVrBt/{!Ԣ{Ez|c> "C$D< AMLS7SL22?tH:UJÆ'Q'U0ddeӍ/lT]**ƶ)CB+ 4 jTazk[x%#4|89& _u\)9+RfP?{E9EtmE?&~u-1 hu3WwiΆBU%!Wn}đEh'fƚܧs0wY" p/vl3YTdߞY3͢y?%wH3k ;.e-8LC7rmy\g#zbsZ4짢zuL}̈́wN=0X6Yrkx?8)qyn mD<-6Ym.,V]aLZᖝv̏뺖$>T )js oUFB-0lwB_Mv-:!춾WMZG{Eq*Pj n9ϙ! ^Xq+Ɔ󂨄zc3 4GF88N ǖ'h=T=ƝSOn֊M)*Ei QŖ}Ś J*{PȲ9Um֒m!m1"bzaՀ2|O]i)z^ov(=O%;~ץƜ62WIH~;]c[^nkex& G?ZhHM|Į+}G'3 |ĐoKV4m4Hs]CAlJJBSo'?rRas#jq# eua\ WK|(o%[~c1-/ Ϋ$1r?/!{KBN1% #|swxfrp63 &t%N88xڃ?+DI> viT]?z0">6է5HpuYAO _MU}`w$Uw>E -9v\rĬە^tOtTsRթZRCD <&,ׇRp3}l4MxQ?04pXMC˖rֱr'Mq4,VǸh!E<B?o<8EBgao])28}_/ C`N;(2(CfCNz'ȹ>P(3o3iX)>s7ѵ)(?"{vW?5-;fU1wp06&ֆ7UTLL7O[pTM}@~TW7~ْK!A~W#6>pY"4CJ,ާǯ]BG2WN*Ԑ?kUׁYiK؉ٽgW;Ra$5D9L"-Fͯ*-3f|ء~j^8 9jR 55_UmX,L;ߕ6Z{p ~1XmՐ.@J n#Z?x \6O\'Sٳue@qOĢCѧ_rz粺-畷5⣈p,Oy6e( ȭQ;@P^~ cgHby%.dnp!H!GvKI(?G:Opίϱ],r|04k/t Z)N\gH -%C.-T4L]Q{8Na:G5U&<Ֆq>7a` 4-N)\A޷c2ٶA m]DoŻvŇT]Gx%j]YUԦJ=(x̷um">-4'A3FpH2SgZ۰F2ЊPEc3lJBD88?3V a8"ɴjv<ؽ,2*j$!'(;.,[xB^9cHpGSEćBL})eDUG:&;ëvc##%E*iAs%fzH?NNQ+u4;8#b *^{f 7A jT@&zCvdEq#'4"|K:ouMa+|+scQBD]_ŲQg؇d=]gZ0W\ ٍ>Θ$O;r 7AZ[,٢]3 wt;kxoJs /pwݮKmeV!7_XPEۨG<*uo%&g<G7_i3ы gޡа8~:,>VfZr(~v %MQ^_D>f Gd?}Y.6?0T)IfMP?p[gXV)WXY-hpۅsݷh8@TF3:iqsY؜~A{5:K3U$A7yLV GFԱWxpPmȒĊ598oߞ{ cb)"И򓇢SŲu=%ݢRކT : lFC ɌVԨ_ɷ%Try\4W%z2ޤ+)a3u7-gƴ@oΫOYdHikk/h=Fl5ϨD":>ׯP]Ir m ,֌fWKX-ЖD1#Nt ;DV cMӈ`LF†oN˼?mSH;'8P|ڔ[нn+a0 3wk[ȞH:1 KJ}`:!\^%tli; 0q)lңpp/A@X{t{w468ޮ`&7R=SN x8KnLuFkjD%M.gGSy }7}`6Ø-:&̛Plut};!O̹BAv.w>oRMNT_HbY!-! d!dPrU[]u=BTB\h6^ >; =`JE+:1Q0Z:D.b9.gwɃ'birS: 6'ZUVB BfNqk"l0 F/*sg\j>WVF2j;˺#Jg1p5TP~4]Wpk/) 틜Ź9A P,q|8~WXb4䲋x~O1*dF35e/>쾾VzQ$hL0ȲMprbwQu톾䒗e@YN\BaSaO.* G'ZUF@Kͺh1=NW:SZxu_wb7^ٵ7m7H;pHH2zGN^hR0{A^T ^4 1n } O(}x" Mi2*3&&xņ?"1F x1$WPG_dܛaD͠o}fك*o,Os6OG хGLW߈qoeS82j]!PV% &"}W[C}>8kJ2]BѬL}^iqP6(Iw:][; g z?COm e [~pqNUV<̻Þ;\H+sk+W{ $KFޙa>2,勇(3镈Vq}wFU89nƤ}¬74lPkPqjct@`{+W=9Œ)/bsÛ"cZ! Э>Pt/Mk߿LoN9(˹ܩШ%+ڪӶmXQ R(jt䄻e`!}y@:Iv_oI"!Yc+].b<^%vf{t̺[ˇgxzf(8 țE~ՑM};0SʛF'91Z ˿k }O =A;bܣ=8fj9Cet!.J҉OL^`v%p>Go{:zm 3dm<ʳ:0#<.fkl$"ڋ7%T~X12w.*d?֖OY145ȡ'%c<4  .Hȟ9/Of{n>n]0:C&d羅8S"eporV.ddЕ <-u|J:sG5=Z1nMe/謧-=$+^"')W9q=\|լd=-x},ny y:3^])|HKk4^Y/ V)k-U]f΋(J$!ذ_P~O0< nF hu^J^z~%r(_0B+xr6H$}`M.dar00DC19+f w$=zH+DXKd۫:F`igޱU- Z\X%tӏ!se낼Q-.wr729bbxbhs.'fXKV*a7BYV(|\vw3AtxE珠؛2=tϡzXŲ8k((hsx|<@R`ReS܂Waeru~H20B(q>t 4hЏ_Xx7{Ts;VtKQ3E=ћ($rݠVioW"ev-&3Fƿ)gYZE4q-0xe!#J~\g`hs(pj~dˑ'a;`rj& /|?.~¬*U {#Q_v$8VN,d81ޤؠӍ 5. |FYa TLSk":sFZbݣ9 : Xf &#YP5vϱSSp}X5Ù khQ'26%k1,Ww\ti5<T2x[1Q<ǎdHK|Sub0VkR22Q:~~M'-K0&rM8ճ\1+ӎ9]P =/X1g_P&:eԼJ;+Z|";VwT^L(t~|gE-Gl ƏXq%=A0t{β,D2[OCv6dm:g{_|”<r(>~A m#9wxE^^U8X:(/{˳񎨛,FwmEdٯvi.ryYo*[KcaY=QqHokTTNjƍ*uB8̱^8g*Iҙw~ ۾?4!4ITmyCt墶<+z,[gA[2D$FdrwéV\,wQo`1;EUjҢ{ 7[qڼR1'B6dӑ,}k>+/XIUN=܁_8Ifr=\}E['QשY!A 'GAV} YA$`D@*^-n($vZ Ӭy5? Pr5>nӯ6Vjn j2J$g+R,ŨXti)4س>͐gFnpoP=1HEMթV2abI*gP3_*@qBbWʻ[΄5}H=-DFhJɇb%,Xk.4.zΡVO*<^MJ>N١B %oҗ>= wvՈ[˗:4!t͋P'VN]Q6]BcHyQ9uyݪ|~K&YAQV`m(j=|k`I[}y-Pur;;x`bVf1BQ܈f"ӎ>BT&pr|KHo|ZnEP?izW+Oʄ(M? dSĆZ{; Q9yDpn 舃{D-(hɘaO _\] ,q:uaZ]Pq6oS)lmtv7 /t`()DHuf00:". 6`!d&+gC= ZR" '>N.2F$OʶF/KN4PLۂ%ooFa)g43poP^dZwSSV4+yGꪵ[E",k<3"vvHHi]Yvxo1nCh*a?/ q8%6 FGu?lٶ'x7j^8Q5ʏX6JQ¸2Z5MmM>HvE!6IiW6H}H:R"ԘH-UAXO?G$I{~Gn? 8 Z=b3S@X.Oac*)}>v}?ynSzE}2f'>j6unH7g9IɡEyoW_C箞Cʔ֖&y[~1`h%٫~dgf⺃> W$[J*C0p~{Fz0:ǭsʎCQY@ҖX:, 4<#Υ;[r`,%w7eFL8VAJQH:g%^LEL/*&T&X =A$ͼ1dkO W-G+ endstream endobj 319 0 obj << /Length1 1671 /Length2 9450 /Length3 0 /Length 10527 /Filter /FlateDecode >> stream xڍP\. @ 4@\4 5\C3sWW-_{}kQihIY8 .l\U-.n'';''7*Nu;@e ]e@g;U@psr * -eN vyN_9KHHw= 6B@ksFs@ r..@{gv8+b 9n j@{Пtʵ,]܁PY`6A=\! (99@[@՟wCp;;!`l˿bwpa! v@7 hlG@&_9C.`-r|r {{w}`(=9-C,,7aȡ ;d2y#899x 'ܚwxOGJ|M|3 p|o@V`?џ ?`!3>bPSӖbuo6^7@HP (@_UptY)`n0;3iA8nif.-H5h.Wux j\{ `O)dv`HVqqrymogF=/;X0n>~ zr> ?8 `8<X:@QO!['p ~ǫ Co$= 8g?s>9,yϑ\Ͼg_g_sC ܬ˿೅sj? }ؖAq@ s9s:)RwqiiLlދ.{Lڬ5TO/W$(yokB oO`5Ӂ`pT9 /'@[6ne<'WAL[~ƁѰZ~)h|Y"jD6rdfSi܉'JTߣbouػY*nbZb"r+IzoʄekY d.}F5[1=݄0#1<һvDRDD5s63gVD𓺝@#N}n>#~>s5~J#%/63pj!ѐ*^sy[WUV{a3e-f;KL1g {bc \Y4wBm$14)Yym<hC&ov1ew F nUVדr ݒL?}R@x߷-F\p~Ď* r>_'1D|WɧZ7CeA 3qS&]:q$[\&>AUPi-t4X];@a_F' X20 :XFHkDAj]^$i.< *Kog;ɬ.Qc}Oj-Aj{7CR()u9JEEu~k&bKJx/jfKx+Pi^O\nDsx2˩C lC/jU֐ |Ckh I!TʛRУdn-Վ z!^,8pxncԮjCZ YCwS}6-AI`u=9!w3mvi$& nS?Ddy72AeK$#7׃AQ1s>8BHY],X4; -lW|8;Qp]dDIAZR b/Z/6 j\0:nmPâ2xrVN!Ib(/M]hI_?.abZD `àjkV+*ZKLU__K!zie4v#!]_Gn*1 ߐ_WxD@ Jo85-{9Q~Rd怨7}c俊CxlolS2FUޕ.kː޿ x%6<@UPf:郷/1] VPTLvcYۿzx/0FGV59[,XKqH@}p߬cW#uYԋjqSm-o^`ֳOOĭHs(9&pZP"@OT$^H)Cq~^ҦKN[ !j3M)d]95I,bkf+nRżæM9g4.mSRݪd^+ 4jWd,7^üqw+H.],mG\ 콭Hk Gj5׉*m.v0k O(!r@' QM55+D>q&"+!3+=%# QD!5;%EU>gV k".rW-1VW ~ne2#C!aB:q!y`ǖJ)A*{0Z,$>YK,ڇ:JyrpߕpjSZ-lѤ">}V~7ovO3V$vrXGI-s!,Kvxqx9 hmfܪpjHfXkYCMj?Ub*7 >S0ăщFR)[IWtתQ{buIRU)̻dL ~L-T|m~g4|Mo8ٰ3?moX0 MƔk1iԄBmVxm*pR.=;|jB9}o }l蠘X!s# tjFow6>L }AB@ڊ\xDå{@al3s<[v4beLcC0jִL=|xz.˺) e6!˖[*S|,ظauXkR;=ӭjGhVT,4V_2UB=hM=v'81Q!_}re-{)n`ԛn0(rW'XjjA[( }(qNUޱ1lO vxJCȎ*= ekgJ9vtJdrXUq)O*ł&ҽD^sHn~}ғjJt6ڱ`A&AZ4;moupaD]Նn1ma<̣ӟ gz?9 q.9+??ͼ,f@d&J0|ۓmz-@[">ge\]*cUN6i_*|VwA3sX6L>hfRxAo{݅MGҭlÚ( l&7𚼔û2;,exRMݝseW QЏmy< 3o":pitHGVvOQ+ZJMה Bǻ6 |e:B.1p6x!}tRDJ=J-* j50qmY#QS&91mM%I@oeJq @U[zb+Ä4S@{)eէs;goT @9fe6!V%R9>WJ,}p%Ov%rm%d8H 3EIs.-2Ѵd=(Ž] 3V6&hV 2,7 Z+4=fs #]CsMM /,\iyLĐl5 ^jpbW<0kqhׂ_@MΘCm {y{Sxc4)M8^81lvvdzH͖bYqR>hr[.e[Pb|`3bM[y+l7_WPOUV<䪮j*|$GTRM~饌JSODbF窂o)gu#} PwجY"LP%-߻'>z1"`6߇S1 7H%%DGS9iY,4;PձUwXERnq+My `fĶüV{g\T`}E@&|Y\li=j"$ѥ\?رBGIՊ^f:xj8:@p<5tV1#K5S`Z*6A6@iZ";Cq;a}> jD=Zsrv!(HGW/ /T/]aB-=T~(!XX+8a=zl" O԰Ӱdb=ԯc,mTb; fiR <gٽMaߍE:&nB=ϒg, Gެ'pYjȦw!W8Ǯ652yod~슱#"O˕ -dԾ-Qs~희4@~YggeW%%c^vOdNw鹌7Pad [.GJ\{]Tx -~u׌o E\טk+nV yfӕ_7q:X> 杦!W};؉>>G$QYSQ>=+ȲrWGTN0?cP1=,LҢjEQ(|z*ba}dC!) }N)IWӼ8aao={TKSՆa%'[Bd$FK]FB ቧ`+9&Rkɐ'S`yY2(?7#.np!zbZdtn֎9B6U7Cs%20?n ;ݯ0%fP̒@Yvs@'0: ( Biqq>؁&NN>Tp4|_%Q+ LBS7JB\.gɆ~f7sX@ggЕӛ][\_@P̐\ojClL]h52/>p+>wP\? !ђVWIӘAUKZӄUTn^#xbhVw{f)#G}=:DŽlVt JW :d.zbk={m 6 6Rn8GB!WC֬jnaN'U4sb("7I@1ut79}.RFY$W_~/g1[\Ъdf.vl6Um$c'$]֭3=vXg#iK3H3tZIz8/;]z$ܺ \8.WČEb.5(k gb;o͈1D=lpt0) ޙ= @in9SRg)&+G8enbxR60 Jt:]$'Ҁs΢dy{j?ϯ 5uEId0Q7bSSG_0e&F⤿˗J޳ո\~ynEBЊOёCnrpR#zeuO@Q7/5.4> C4 HbË]Ww͂1ekfٛSZN#yR3 endstream endobj 321 0 obj << /Length1 1583 /Length2 8552 /Length3 0 /Length 9586 /Filter /FlateDecode >> stream xڍP-Cp q @#ݸ[4X ܝ\ nᒙ93s{UVWuk_MRMU jBX9؀Ie >ri@t@.`(D_. sg۳2Ppwpp8x9@'(C @lPf(@! W4:I 9 >? 9lf r|hiЄZAnᵭ ;'+F vh\A. +*掠?;cChق]kB<]@gq}pX\JU'Oc? XwCp6::C5PQbsrcC~;B=TnW?7W{.`'7W6Wy4JO |7'kzB|`&ܝص!`gw_&"d6 7 /K[ᵼ@(9~;u:A?h ;ߊFh+dY ? `|38_ve M=)?;['!rqX9yn< )`Ο`w,3iA8nZ>q?3?$GmvnW>oMuA2 Zy7=8=F dv,ʵ/R*V tϛei|s>3yq;4j{8yx..hg"q|9W l۳ =5Dv?7]o$`7 -Fd >{ >' >gq|!ϑvD.v53Kw[V??+ Y-A-Zo*\ v,oI3\-Q=4"G6'=&hL-LRj}{t oPΏ#U[m$bnG{"C8\Ybj$7V &S/˫i'*f47\| 9iqvВS_L{@4[9m3Q!0mA%NW_1.dëW^AH(>2(ueɡɃlp8W~7G ` `jS.h :%,^ ]6yҽ._$qԦESd> ~SKk^*bk򳵅c뛸9-qOErp4mɖgq/*6Rm1 .}}nDn"4n wҝݿ޻bڴj]㎬|9:[TKh#ˣ<%Ctb%JXYk=~n{\V,E?*ې5.kƒ_,a䝚qIA96cKIOeɧ7jI˺Ma{*Fl6?jw3\wm*Z?/yIkKOϣnR,`en&4wVеtoW |NzfMu<1 gO1U9ʬyQ㧤ف롘[laEVALFXKtQc5m¨h`@RCLFU\޸x ~xiN@cct+6aVV ;!`KJgVj_Vб˟~3cL, z<\tpm3VXT#.Ӵܣӟky@T8U7 mrZ'SH,FFZ:"ĕ-mb{g' PWRWt a\kP-ɕAn0~*KEh,N /k͆n aWuc4?[ .wu_vqxjDuhm .~ǦZeբTjzl,Siהc{v Xqv!-|ma7zC:UPk[)ڮ*-"ý|v-qvOg!-:3`_#qO4dHF XKNce <
|6rQ ojXs^`GH).X,xj9 ^{Fn$}1q\? A+̰a:ߑ,"^_=\bO}c#3Œӧ)ň>)aFFcw7۸O5,Fۺ`ݓ]l)ÍV_&/,|++*۽IoLXz>cVEv->Ob#ݮ< K4-x}?ζ4=Y([O]N'4s f,abTK]4̷ve\9lH蠮;bdp92ΔڠvG+df.T+ʂq91<ಢ]eGoKeNVl5z {R=&>nhop#LR:_ꇦ,/aMf8~Hkʩ,KJ1obetXFԍ y uUv;"JCOa!vѵGm^jLďtyt<<]N$a#e gތu8DLQ6tIb0bƾ(᧍ ޻ZH# z<0fed!, n e??PLHGp=y45UvKb'B(6\;290$K'bboڑjBx!GDнvpfIugI9 C6(st|NhVbozU(BTK#rPE֋ەKH儍KVt>-!k ݢ+˭§£o1jlC3+{ԛX:hjÔD8 uiw/Wa16;CՕG楚٢eFjˉ^QB븠oa0Rag~:u,41J #VNНfZ*|=fwT*eǶ#PklpWeYǩ/WFZExP PJ|.6AlJ Y3Ek:VӇoֳ7UMI ,LM^zj/B%j[M1$C TN [`e|I$HPMH{fX)y?&@$Oz: Mk5Zsq9bAe_Bs!-2]U`m úsj+*kYnް*R!FQ?sΙü+!h>F[T k 62vs׿ zG+7L]b܎bzvAb"`Yu6o%4 o'%(_=1[?C?{DcEVC'@??M;.ÙrMGKfVayĊRi`M6i  uR2Tsbֱ|ehL(.qe&TpcQ!Lf}_(^R7;GAS ?!gY{a)AI2fYBW1|,?V9yA9dFPg,㋉VtW;U}6zc%1L^CCxI5thv.EW=\;) by7q cA=~n|Qc-{=TH7F353~Usˆ*}9w~~շwVb%WWt-IWQS" }ӷb[4ukP>H{,D1/ٞ~tQЫoHoPH㖈:s(fNϷ&Xb 9 Ȯp~͙?D Ra{t"q~8V|6Z2--|0ɜ2 Wצּ5zwM봍n瞟Ds ҞH qPY4^mrsJF˖D&en濑"jpR, JnW!"Ln=Vkb$o ԋ_P)Ұ7}|Yہ{ ,KO Jt:HT>zTw&阬[Afr!Ax BDNq}-@[,O[}p̪Qp hCk BrbG =WTܟJrϽq\[zA $h,=p8̃x4m]pV);w67 ӹCʔ߭@h.2O{=erebߛUPm°{L[2@I1QDXVL{ B.[-2Oѭ#Z8{G' p, H-9uKa8cֽ;]DorKf΂]4{j7^Tq:Wː /Sk3ꥲKl̷3qڭiX-gN))ӋjQzT$( JIN_\U8vĈuEi (?/-TKVZ~,8ٯKb]"V9FwSCŚa^"`z3aͧ3s㶨4K*~w}{Z؆߶j%"c%);Zp _cK~cu֫Zx8 LVRY1x%OC 7/Ԋ锉֥7ӛ򴐞a99p|eMȂwp@_%FpU)#3_@ߙ&PpF|oh^fw{9#;- !S(~*RZf?`lVj(6̠;&KU͡H6fGkyJ%%}Gni^52uacY_O &0~n1?hƐjJ XƜ^2dR-0r/J'}kUYfP-+Wѯ. N+Φ0׳A~X.#N4Ipr'/IMza$&'. m(L,lP9J 4~OA23-ۡհJ:XB65T pJiFa1F,%W}by/ uGQ 쫕6xW91]J[q_Sm8^U] L"#mJ$H (#{;H sjDlь~oP/#Pe/"\7I9$_\2蔮%7і09!cXN R??5VbBJ |0*)zí+HoL%3*j7¿d.)6~2~</6`SBDBe;}G׸o3~ k`6DB[C;*c ov*T rOE1ٞصyjW[ ̥ݵ%B:Zh ?G* ?j+(%5Y Xуmdz7H^Ǜ폎G} -]5`'_9 =ŏOaS12(-OJx6A?PR endstream endobj 323 0 obj << /Length1 1373 /Length2 6096 /Length3 0 /Length 7038 /Filter /FlateDecode >> stream xڍwTl7ҍ #FnPBc6F74 !tJJ7H! !Ny~;;gw3 #E@5}I$&f0/- !ˮQ:qG:n1,d@>0G@z~H S_G "##%'E `8@rc*BnSE# !+,+vB y0 E@ݡ"\`^MN(_0 (`(  w"Sm=_Ww'!;`nP Ꮏn^L< s;`4h y`n'd  GyOB0[sp/<௳ {Goas8FE3@R2'Nnc8aF/BzCA08cPd#ah5<'[ p7\f:VIU @ sg#0.@Ն;!25ҿy&/ B< H|O ݿ?hz6V;o;( ]0ojD& u4 .A/oP#ˆahxaŐ%5ovJHH$؏sI #a!8 ` 8!$S\ y~+Ș:(_ H$f_NCh(dn|TvVrWpmDafW0`0:'|S%=W y֫ǭo^%%-VK|GLy=3"C-MnTHsQ ]]0=f^-KzY6!`oV X;NKG}ts:oU'$h'A8jU4|LԫɊ. 8WFLPi"n+64M,lgA-tejq uY<J |~ΌXz^Pij<@E{H6̒z*֪r6YwW͔%IOǘ=OC SAQ|`jo0(97!7q3TX ~(r'QDREE9/$6Z#Q QiqJ :uܮq=.gmnXN|\2~eZ/ SߴJ*K[ "`AOt>>{{\S*gȷ ^5Z踓݋|lQ_tzO`Qcvԥ{c5.qv]_$[7(4$ZyP,l#l}"kU[/-uinDdH>pG+fܚz`{AEWrkl>^yӏ&IqTt>V48˳mXmǿ`Uޒ|9]\Ti=&Fu^V—LkvCÍD9)'jgVߦYwqHARK=O՜4r$.4me] 91 ts]4)Vyv!9_"~ d|* GM5jH3l=xZʼnĨ; i8=GH=y[B~u:od-t$х>gv-VsOzmvJ/11r QqΎ!enIdRPY)/;<Ig^\]RKlu#5dFTڭ`B"#ֳ{ 9T#t,E/yi-i;Ǘ dZiiɒiRה"& NJA3(oSK˞01/|bCFCE@7{3ZlR}Qj5ʊA,Qx[4GG\8Yg3X^b%MƵ^8ٱڰ,X斞Ѽh,[gp0ߺj)yq_DnPOgYҷXaBs+n;'h=uo ﱵUtxZɷ,#&I0SZR=. Ӌ)Qw([r}FsVoȴ}0jg-@B!˓Tn]/Շ5)ۜZ,$Ģ'V6֪vt}v pgJztCXL Aw'*dw~in0>jBL[=lz+A`FR~>,%fC3f&n)K"ֺEyFM *VQg)&X*pǀ #Ȩa8@Gg_(*1lF V_Г 1ՎdT[E+bE蒋:y`=.Tfvt{ }LTzJg2U2f> <}՗'CoB19BųWFsXKUw'w)v zkjsȃZQBM;,/o#v6>,l "" XV?Ɉϑ7AEY ?0Lj3U5{ȜGͧW #M0z^#{1zD(źMU>)PY [5οДEG>>PۏOj:-%OԾ\И~\8 sXƭrH/} L^e}NO.( į{? qp3;|+q,Y|(G^Cq/&?gIU~Hgn›k-W 2K%#[j^%M#҅HDrin󓙿\K5r} я;9Y4TjP1c2>ܒ_hL[_^:cKMWf}pjgݚ7sD0T=[X鷴9I UK[yV$MyS8gIYܸ=̈́6*w) ]I t)Rut6Wp8W' /FUT\p+s?zm'JUDǮ9WvMhNw/zY -dp ќ{ONU)vf63V{dHDBt~A0u1WcΉ~f,Dǜ4/kn_vM (mF簪ŔK> 7k^?~\& !i"뭆l*Dە@NȚYRGEѮBȻ .Ⲩ+CTZm0W(dI?r>aV1|R43or/}Be$yى9ْ?N >#~H1*3j07}iON!zN$WX?;Av5njsϿS2PpMJ'OS_>k:qt3 NOߏo8|\n%T64*xƓ䫂g@S[28$7]oN1X.6=ߛ/$9 ţjcb!+Gfd$7t/y5:)vTp<^!cq! \8AM4 Xy'Fgؾpkט(=9O\rB['B3N#y &u{YfrHT'By^$."ו3O.`l8aIE@\z1~W<<iq9<ɧ>}X{ǹg'cԀL|}3usnB\"އ_ QI0,p@v珆ϵHkgiάphVoӉYJ9abV:Brc٪=]Ivo-b D'񎰇l,bɧ"صa{^6W*8{m;J&i>e -`G ? {+y^PZpvy*s%gSE| 3IG$^"汞JQ~e!72}{D5>Ju.Cϐ+%Ҭ<MHE_dq uh;߀TF J4U*7-"yXz(!B>u|.;֧H4]!:H;AJOqNJwOWXyRjYiiκriJ#nPQiYA5Vb w7cfwSY~8UQS!6s8:&*,p>G5K:"{ '2x+Ԏ1%_VthE1myZYDbAogogܾ3,楶`U._C@襼֣x VQrw7?φҤTo HW"I]:Xh@wɌ#83E*4<;;A x3Q=a×@ ~Q8 54~lFk+m{lv(V?mxnnNl:"Vtٽ /TnkΖM峣q)mF[6Ē)CFw?YIXȪl](72)-ORT,^| [nZ5Dlqq|M> stream xڍvTl7%1:I(nI 1 ch$$QA@$$.%E@RywW_}~uc3QUg\ ŠB@uCS ,!XO_Z8F/:uP,z!@.X(+<08rc@3]m/8/gD_ "w'BCa04 D\.O8𶖁6+;B=}x u;i R5B= <Oɚ(gu4 Ga}@`0G: P.GpY޾p]=*tp,P ȁpo << B{]#C.p_x) 3:](pd1]0x ';<(Y.HZ[B68Qqef1"X] (W[W~o_obG,(ۂ0BoGUBxb7DoWK_t5;#|mBPEz>Z1 s *-~}( /U0ODο%.% b0@~xI i ` H CB.h >% [Gab0x8 aI4=Wr)Zf 1-4d/s"1Gt5Uf/pobRMςRLGWS#mpQp_x߉ n$l1.d<驘=jRZhEmD8 VR(^C%^0 d+Qg t2幹O; +!Ç8 =O⹢q[ߒ8vڡK2 W}\nQ6 Dcf2]TUyIvp\ uyΟɨy|uI:.\:4=̃?nn jnj-7=. 5\<~UO9s}e}6aHB@: G!ZX1"-(q;E}Z5eРrz-i,l%mղݚr1SB sZmB8$)UrI1՝2v/GJފc{vmf |[˃(~)ҦPݯt/}5$Lȏ2l\}%6r:JGN~%@8>.X-z˰f7*sonή?,ʧ?tXFԐ!uxNMg@ϖFy=iK3n3CHxN~MsL`xm6agA8!ZЅ@q.ȧv!@+LkFm2~ϊe- ; , O}]F64]a4M:՛ @G+&IsFROr!_q*;0Z]ǹmUJM3 ΊMQc_SNF%ED"ߎ5+L㖷24jO+9kD 4w| $o"Dž8a#Ӌ؛zg]1<>^|HNTQ|ƽjHp8~D/g;oI*oސ^|bHC)پˡ3+~_: )Ip^ߓ{(Ux4ei zV[b[hwe9&Ӳ_>9.X4VwO&S ؜*> g}YsrN%XA{]c*cYJŏ4_^? AxBCy޷g{(rGBtY!NvV컘WCJ+ܒ7ȵ{1Ŷe4 %)Ԅ1jɰ|~̅o˃qlk]#fCpj7~`d.&sC'-M7-*2tS]mepWץ>D,OWniLT@FFD{kqOm.pf&P4J_M|EtjqAyM⊒UMTj~#.'1HcH,.[(vKl4i$1&DϘ)6< n˛][$g.7̓?>n~`Go*q/͎;*w5We`GuX5Zv("]zN|Hsu8nmrF^ɯs:Μ]~G[qU+ҟy ޥl]5jkܟ5ѻL&ܤҪ2#ygWxyAԶ._W}`2[hV%!Ҥׅx0;m lew|CwVs k1md!2U*f[GyYa;݌:# gD^`V gOl}wX`[^jo L6Zaumu}x_p$t\1x`Wcؓ`ܫ[l<{ySPen~ƀ(=4{ޕnһ6gצ,e9Ijl,_n Onkw^ޥ>Ǔt%G^w~_8?_֢[לT>͒@)5;J?v~ jcSۏ$SLʁJ5@+联Z=]Hxt50ꨢ\_|J>kdsۇEW*e'M}eRt8ݖ)"%W#_G|يVWlW;Q)zcK_ pu ;- D? gKB([;}r mEJ4>sYo0 ݼjl3r m#^lS4)JlٞPxy@c:xFf̽$K *!j eȀIe^+qzo3i);\bG?ӓ o*(>s?@2*1u>M NI6tB:S PBq3EKx_K^抠-/WCI\Ow8׼NK\AV EwMSG'gP;bەQ{m=X~y кDP˲B'XꝮVKZ&=߽'[vody_=0֛i27KUΝٵx/~MUCgiKyD%,, Wk;{ME^${3t\{͌TfKI{4'-Ʒ1Ē!ܳTŎFm`JHfj Ki Sh1z/>ɉ BJ{2 j~: 3WD m{1 ӷ1$桳! cR%0:߯:|^4ĵX: ;hFJMh(f7ɬE_6 鐤=!B(ټ nER 9N6 2_q|=9k^LuЉ#nf&/W6$~ ̣#̢{u=Gb# >=\/. ~esmZ ә[{wZ ~ p[<7?as:YgAh' {!Y/̻|,6nFdjxߨjK)q.יn9o gLvt옇麵j#ҫ3^4"rli ԣ3ˀkbgӃRk-ρu_2)K3&C)!1J66΁~ۅefR%|*\-ռJ՗ #^8UVWsJ`u T>&gb^pj娑dK{ugke"Kmi{ҷP_) EbVY-F] :qto/guxB3hFP%G`t0kˠ -䍝hFWeYOMTq:&[ovt% gu۬!'?gBCՊ.`)(p.iG:I4.#dŽdٖحbԝXpaAybFP,r%[L-x\^-eV吔UfޟIyM>ЪWgC?)$K|FTop\NSܳE}8 > ȅ9J*~|"UMcu%F%\A ]Uo*$Hh$ve{E6UY$erXIX!|?Fyj5`eBEd}Xܭr3Rl[5xZ=J?g^ 1JұI4B.c?3{ʽgìKmϝw#zQ.l[]\Rt|ҍKɭuB!,e>ʒ_%g>2>p |mS |^K-/kUj_[vd~Q36[Id<@ )=)5Vxv׫S(ȪpEHs\`~wdpu-.F>CY~MUq*kw ӚӖdZ,#9 wҎkz o~F_vzP܏X lzh׋LsNsig#:0{~D^ΌUP] Y,gu7]DhUrzb;@}M墄. _sO=yQ$% ewj:ԑ6#ٴ1+˥W|p{7UV^0k'لZNTC.#AlDu,"Gn,p|ωM0fy&)+n㽝pa+`Bե,S}w۷'[э/z!slUj944! JnX*ӝ}IP-GU):=@?[|;bL#Ykv/3|kWDtY h՗NZ!3k&5c:$j &.k@ǽVPfH)~ S#^ݭ*y}G$D B*^t7J5kǪ/q9:F1=P.O`$D,X-\:~⥙_mK BCL1+4:JJ9l7"P~g)8{n2ɞ N⑝4'B6RMT.XJVs09L,ųhnW'qG.Y,Dݟo;B=! &meE4E1RTmw$u[3xtGB<vMS㐟߹R.ѱ$CDE%~zKg?1P endstream endobj 327 0 obj << /Length1 1992 /Length2 13194 /Length3 0 /Length 14412 /Filter /FlateDecode >> stream xڍT{6msʶmۮ W+mLlNd{m7i{xzZ?N8Q(1L {Ff^*7BBl^ h.7vy7Sd]m,lN^.^ff+33xnVfF,@!rtty?jS ;=@h2xWj~K^&&wwwFc;gF = t: P4#@/ xZ\̀N5y/c p{OgcSSPgtpۛahl z7v356y7pc s6urpqftC?¼YL dgwqF>q+'=\=os+{3?Z0su`Ұrtʈm.BGftp033s%=*r2Av6v\\V7B`aYLVDw1 ޹e2*iT 7' z(VW9WS>߇AXw\3tcQ/HCYz竫;@`Mke\o@?Cr)[ZE=Plǃ``af_2y4 ~4Rdurp=W8,gh&F{˻ =_9 }rd8LA&л?0i#7`2b@c YLAV?d|__=?9ޑŻ_|o;P|/-)ҿ?8 蟩vt,YX;t|o?hge x?O&K'?#'[yT߳kA=ߧ'/N:O7zMA|߂kEf(i]Q`Shj>o8݊ HP/|֒l:׊830QKA]xG3S"ѕE9޽Oʣ|e4t~OeS|!F#Z?d"${ƅuvG:ߓ"oM؇9JuV.|r|]`pΝJ@Z^y-Nr$s=z0%\)i,?cX"Py;Ѱ/{6F+$:tn*o 5(WɌ@Wmr{l qBDr7[mɛ |4MFh%zDVJ:csڑD',\~x9`De)Ũ !SvBl 'eTp'ۥhtKR/9Dn8Pw,m=k}MG jۀ0Y!6aтSQōJ8q+c2=rZ[8ͯ8A3+: C|S欑M9#n#Y46c-DZIh卣}?i1hCYJZ'q,D~mHhC—Y9K=CqTvt/ hr0"vd:m=9~UIK(1" nɀw! {;VkkLzwn$(x  N/B~J}8>E}_Mo?6jOoJL*ɉF&Ov8V9'hj,`i Wcks_q`N\d+t^%۸z~#+-c>7eS>%wZks{ظ@=/|ѷܼ߾ @ʢJiUxstRM=\OXN@K/OЧ`a:}ySތ& vՑlObx\.4.SA]ӍnE ad`nc,XrekEϔ͆rmI67nJoK/ig܀8 cwcGPL󇡛*FD[Gm*"%eRI2ҩ(W ~ƽ6v^0BMB _Nj`Pws"/Qh_UDq'zE5#,PO+>ǭʮjB Jo;%M<)3ϥ\ҡ"isx*!͙z[u9|2)B_VDgg='!ɟ("Hw!&@ <b6;c}>h|2;3ԺPbIȎ3q Yg4 CHfPbн?h&-jeE, ʀ @4Z#N:B@_',<&f!s|mv_f]UnؚjoN?O}=\AY G9ſHc|)L ӛ$p!1=^t9%xf#$͠-Y[)n!KLxnT`BW:Hv@mF觜 e|Xޣ'aA$A 5YBTGd.1c1*E#*u,.8 g0(Le>T)E(hf"Ĭ^gi'zFs]g('D˓ԂԖ!D5w7 z~zڄ[%ߠ cxk5"SO#=SH,Gwc 6-I ĭfŰЬp*Zj KRK"biMm# .Hw&&Eg7p-/鯅`/wOORmmd[/Ք'udIμY cBgBB>˝-%@Qwwa7؇)!:ڥ*ktbM.eKR.hI)Idz+1c({K= }mG[NG{՛'Q"9d| R!6s,iH]:45#4+ͪ=q: Z:g˧ jtiTA4Z x8,'0k4-ǎ;!=f[3:gh ,AtA|lOf2'鞝[騟%RXBNj)@qȴUǻKa0ɒkPz6ޟFZ 9)'pq]^H%q} ;VD#pͯa9^â97*E3ddDl[ۑU4}hfLFWq^4Fwe*jևSπoV.zږ)ߎ+o?H` 987fdF1 x_A̬sdkV$[2IM+o̧XGw]}}fmۆ,]`27by%Mhl؉c&_󻾉ư䉕rǀn2WlZAUF{!GOm JO!#leqŧK)`#~!ɏڻ6x7l|%>B5E 97|0$QJ}֪2|om~u!k{^TB |҉|%PB K#LUz>t˖(y6tag^}UϢ!p7 VasIu*7 Z#2Uw5SZKdt69sS<:UbbӮԜbC&a){fv\N$:* O 16 .eOX D2mڃ(EO*騤|&av߄`;Tg&# fOeSxn?$3ť2E] 9b `h**~[h}#'!=gKE28ռ||/iS X&U-a#0D~^ Lի)d R Zפ*LpFeα+!gαU&\ޫ>X _Ptx-E Ww]Jf`\doKWSM}m/[ea,RV̛SeS>B^X]1f/W1GH\A_ITJnsIUUJY<"FẊ>wxP~KA!\J+iŠ*bN{>Ȅt5/nY.J]xl&3Ao~Hu_m^GX>_{gDƒ_4ʇ^Hp,ӭgf0i+^ju gp~pڴ(m1Nqqx@;Pyzt=`2z+sO -)Rb½uxl.r9YPi&~ov<оjVDyHǚ]NvVJΤzvљכMmj%7  Jh -an'"ͺKIOQN0ob}z왁ƕ>[bTJ&/W/ۼQ gla NQq`xK6jݷٰ[8HՎrI2~xgXƲ^-g:wbtbrԀ ^z.?mk%D,zyS_ LN[XQEjh!{| s턧!/A +;s^L$e70Z# GV@p(c~c6.*3(>GbFY(*3O~+ȩw[BH͔lJ? Uƨ2,"SԿO94B2a(c- eUϱզFqR%bEWhHU 1;'zRT@gpr@]lA٠x`ZnDSdHF"Ъ: =1WKQIMޕ""D}%gHp7|2$4,q[b $1n+Pf&ZtqTq;=lp`R}Q-91PtƩnBE_G)lg^\s9D1Q4Iޓp0up)J׈17 ydisK4Rփ:0=BQ9 T{~.&k3$qb{YkA߾!N7?%8T9NtM3"v0_]wr"(~1CʒU}%e-ʟ}:w.-wyn{nMǃ `]7Pj׬3`j8 ˉE=͊):(+5j]xh wfgEx.ޠ(]e8oH!} e ]TDɭ幔#/q HՒeZ^N.0Q.arh0V߷qk(q~9dO&HxȦWc*j:/ywξ?[&x]Pr2?}$n &@)3La6\sRɢ4{M:xV21Kr ϳ>_~Y#8t v:B◤BoM9RMvɌQ .sW#|ӨN(:=I>wLw-*_z_~4!*,M*,>YVYYbsabQ Uϗ J?c#ࢵĽ|f,J/g,SER IA"D[PZ=d.(ZL!K8ChA ݯGK(K9L"OUxwA+WfqrS-!1(0ou\D"EAR+FtUR ޽өa3GͻjdF>R Y" 6` Lssk~Ǵn Qj꧰f ݩGK#ꔣqgFL u%ĸCxMוswi#s=}EUnrUڇx# ;y]\o!pI%x|kKCz7O7a7>9}A{eK긮)n+v7'ß-{5É1涳]S5pzx׏z(bt+w$([{ 팘 hFLS]ifGf s:b2meŲMwoD!*U㭶N^LkC1^F;Ax$#a5cܒ'Ww+;Եg =i$%.KY~IiSCd2_t.MO܋0s(kP*d=/p, hMHw0.HM4$54~Q8Ro"484J}=Rеn LfH N1fSɀ8o}ظ+u u;6='v׶RTtawMq壽n,KC=VM:M^!ϛ5" P9!?wYJl}fNt)pa uDZ)Ea&*\͍Yh[пr~&ɏG{nlȸ&` ?Cw[,#UOO!.Ex\ǵEctyei, UK|{iO?9rI4jbIBW^sh<{n`fD#r&pé69QxGz5Bѓug{>z[l;M~{-Kᮌٔ"UXBT?x}nLULeqQl;Q.e:5yBw5$N-!ɠt^`8Mb_NJ~GN*[/f_S!;$ھS 8зAv؟0,0Ц::i1MElK̄)@,ѥ4s6P!D5$({CLyyd=_3>q՞ow~yŔέb+#? wI!HwFOP$t7ăĜ#ja+3T_qiȠa^|XOۏ:@ 2N3b}MC5A3gb `3H!N$$2+'1bũ_oT1̋pSW BDt {3˓!Y P8hmET\9a?ogbKE!$g #━y낚1x #ݘ(tkNARYg\ ,Zv~h(Q( aIcȵf]Z>do3"+H:0=ξp| b!خU B &.U^=PT_dE5#kh:* X۴%7K5UͶA6f_8TQц#Kr;c]DpR _6u쉧ް0UQ4i3JƁWr]ӧ KSzg' rt٨Yh\LFac0߬ xJbՇ|,}yU'^&5{;qxymD/q&uԦ`*6i)t&OJ=)tO%m;!삡 'apU.|:_Rcf nCx;(\<& ܓwMMiCw;?/ Ì*A %'?}=#@_uP՗JG?X2s=k^M`kz!hn{*=gnca@=Ll c [PkG<]Eko^@rՈS&q@uj(rW0 ָǿ%M: % nCYE`ɰ !6 x'~ " :!V#I.̫DNz> J.{ -,r6Q9J?swIRG皌դt+(*0erA^3O_4PsVArKQ#b(?tt"ɩZcM-O-[6ndc:Nn`&ܬӳ<.Dih>Sٓj$}tȤ!Yt9m+rz&h51ˠg,wl91|8Or #]"' X5u!Ň(+ b;Hݫ5NY:\(7vUآmE'56%ojnլм$~ƾVfH(LjZT)nwfE^JþyHIyrgN9%/$9>+#? 5(Z*^0>I'qae! SXK:tbktG )0/Hk6P\-dPGw6;QqK?*rع {{ץ%S2ܒٟ^|Lp)_;^^d4@0lcc5 GQ6E@,~p cو֪ |,b, [0ZTT* I띙KVIF\$SX<)o3sU F| ܔ[Z|;*㑓@vx p"%.  Ū=MkD. ö|06J~$ eT;Rc,t n-EOq1"Q4 عjBhah: 4U93Kzf-I8 7{VC"1| /_EsXs!|'gɳ؋yJfMm%DiFhhSħ$٦YnKȋ\ ]f7>bzejIE-3w&j[=7Fy\@2Pm,zLIn-IHQ๭1Qhlđi\@7bA;r8n0\cAGT5fP鐬{vI-(Dp8 yp+˳j/K)EX2TXŞ< b-k ^(M%#rgYv ~l)hm=oۭQGJq)D"1ɷ%87c9r8Ա$]W=TQ])h'?`WӮ5I761hcĈ`a"`J]6هЧ>n $ v` GآPm= twd[]gd;0'v޺,lO“r!4ww69Cʘ{wC}Rgfo#ןrE(kuh]P7_8in턏$m[Lh_ǂl8W>/0M.)>u?=,TƤ$&eDR".m _?/yi^)ؙG1߄e*N${$=F W ٮKbH)#8%ZO" Kv/"%O^ta֖p\U\DO4X:_|N Q)%5n&D(ՙb['áTO\- A Vp/wлs>g,tc˦?PL'${D#6;d3!9ٱ-GzqPR(GwrMQ=` ^] QwPٴs l˕ W!5H+Xe}껯#/; )Y10zy}bCwu}޴luߙfJO wPWՒ>7'Hvw$M)8h| IQw=gحG_&w00vߣ"0P RnS#:mM#˰[K6pxy hJt}ᨒ}Xկ㉂)j䔣9`zei\*}n[HS)v+Ji /é~J[ O3 ;QOzdg?S/eyR :|q)`ݛZ dO20Ḏ֧1 {݀3;< endstream endobj 329 0 obj << /Length1 1409 /Length2 6224 /Length3 0 /Length 7189 /Filter /FlateDecode >> stream xڍxTSۺ5E:[@zM@@{'@ $HBUz " HQtA@@}c72^7֜;LTviQXQ6@b@/9m'㵄ych@yXM (odn Po 6@싀 h Cƫ Faqu@ YYO7F X7'"!6)ݰX~~~b`OUQPLa/ 52 3/ ac0΀D@`( .ypf:#//_@J'W"w0A{zQ+@FbX4. F .8M70o#A (+ n5PP5' ŐO =@z~Wp 5KQmsaR@Yii)v󇸉*`mqcBp,>tsEsEgZ}ucBŵ u4/*$*! @ 4@FF <`ğ>#VGdjO"g.C40nBpC,%wD `O2\,NhP %]^,+ѢbM? jBb_v_zC"P0c4 ˇiu5P4$`oopq+)@J(7b(4~,(wC`H,1.'5a0lq ruޠ'axe'>f0N A>IUgh}`VO —x몇%#_8hI4i&TvvV2}?]`6mewSjlVlJQ.=.U쨍=u2]%=DjW"׀uw^ ޗ<*믗cU4>LVǧ*uV\÷L,}t3mXҧP-ݗ>Mhy#6|Lmn" yTyx9~BqSOYteՙ>DΝ@Y [J#9Vo.t,t:\>c7Dľ<DZsfN^ty>τZw=Ց:}Ec)!m{uL)J 5-."4ђU]N*1ymcxvJ,5%ǧjoI|Ѧu+ xwi^ u5D.އz=nΕ؛ԋ-UCbNtUwIߓl[4"3{gBםdJfy6͟eT0wT95EC}X뤍Ի%+9LFV;Z*hY:0> B8Pu/h)S-(1<7x+RI CϽoZ^l:u!gK}/nm$"@Vv8+1m46)s/K5/%֝$گյW@3Gv{|;߬ 9M42*sSfOe 952؇sh| ER;*ʗH|sHa$S>gSR "1GϘ W(d.kOf|dbJ ;k%sΰJk ׿|1 K~ЬBd'|JR6M׶R[kzcQnvdL1ñPߴ9!fn7J] /(_׌ K LȺUradV[KIEld`T3#^QZeM÷biޞo殩ḟ|{6X,58 ?}ḕшb^M#Hwh{ˌ=_ Qʐ!{Ew֬=35SG4Y)O1|QQS? )W}ZjZe6.Kʺq3'S:ʕVUY*E-嚯4NvqGOU9M(f cCP^'P#Kͳj( #x1_kxW "6><|11 s8R!?r 3rܨ~9UnlM58sx]}z-}\6{whwCփ<&E;=KE}: ÝyT0u4ѻ|@-5%nވ`ػr?q餱rS-Oo~%8ҝqcaC/h{+ "kzʼЦiо,3LG 5?S*=x~ob8εA2U) ~K%D/-m|歡rEOKWTtUeN;N;Xx֑wE6yrnG`N Q%]hlν{ž){IUsaP:Hu[VcQ먛_~ʦ{&?L, OҐq V@j+TCt,{+Qu[)z~& @tb q}wO^8OP8^pNvzlʲt0c/ fB63XGR}S(HԣeRRV0F1*)j+mY&' e,}X@C1v7#ohHҸ{m4 @ɠe#YoTʻ-4OM wc NQIwo _l\=~F*䵦9L%J݃mGuDե]m|6>ח-be *e Hعcrv131O(ظx '#9dCJHs`Z )/s-بCŶ5XYGǀXӂՎ|1n6? s/qƼ'XtrCZvOP5^U˓< d[A~DNTRg嚟\g{nnmTҮvy2y8FŹlyf IGlY'cc8ӫEOֻxUڥ{{Iob֨Ik/3V1̈́44E(0=s1^##7!x//֭oȧyCEkYϣHJ3j[煷^y0ΥP3Ivʫ*qH'm*:Tfd/ZX"sSه/ xTkL|OGW&pL7Y΄Pօʗ Zlzq9Wt_a|JH?X5ݡu,i[`x}EtF@{ֽqsZ9[@qzEZCYy7k*.AF:hy=E\1zM7lizzC[=uUw^H&s ]VŽ?`3ϸӣ9}ǜ Mz/jRO @9"pϣu;I݂.X_AaY=I%<&'Yk7yհRWrup0+'MZGs4Vo\ؒL|yp}$DA%rgmW D%wHN p5h۫tX7afk񟭩gwx  (p̣)lh_r)ΐ/_kICV}[LOPcܸ螰ha]uŽ_,΍;&bbkflz`2tJZSR5OYՃD9hj"OrsUHo7?~jhYj6uc!{Y*[[}ȒE$`~ue^MΈ!X-cvm:N;qaj 3Wg3/¯8*ku.W8^% yj_Ff(/}te$ Cw|WwzOB f%^$U9|m,wƗ35:zM(J3j|5]񪎜R1yY@S ti.ӥ%y`c]z:RtcYUKYWOGw#K3dX*S@9=כo8ro7}{k=vxEnRndx&XPqDl{tvZa73f{y?߅;{EaݱP)R˵&G4O=`IhD= 0:Ab^&ufA<@-'%~"_pCJKoݬwZ5 P~XpgVF(>O>;L8 ࿴b6ZHcK|\wxԮq*m(~#́.P3Nh{BȼXJit:mM8XM*:G9~)7^^G>1!|ad.+;7]X|U!¡J#Rq|Hvc)UJ}̅Tb3 ]Z#pocO>W0P[T>ymtK u_¼U$Ͻ9{o֐i<4 &ͅ& t8Jl/e6u2}9ŗ ~ MN?v.WƀqirݘJv;kjBa9UG ɯB$"}PP V|xdg CBaΝZ !aB=,[_MdAcnɏj#2^4m lE˂/qd̜=Kt&(P焰 +YExvHS@$6gG{MLE0weǓOd#v n6M h)7xCIDO`1Ez4 Dnm:f;S*qŗ,ocw]n_ L!-yI݇9 F+*X)m(~K P8bW rÐCUj$J!ru쫃,RQh RƎ=^8G3~O\K߁I]g2 =5Jio0&AmZLbk3dOu*m첳(u 24P1G'`^5x/*}0g$rX[^ˋj$Z|r4`R J#~_roę> stream xڍP #;%KA$VPP܋wl9g{'3Y7 -&%$X98Z@N7 -fVBe! 2=d`φP୫='/!Y c(B! Zi3? F ?˟I3 P6ـ3Z4`B0`Blf.lPgk1F;f@?Z9n evK 9{ 94JUG/c Xp{ hCV`{@UN cA,04w>̟ , '0{\,06=y̲KisA>3yC,hՑ]vrey#\aaG-OGПJ?=z;BVm|Vo37  ''l?AVw{q<ӏOF B=1ف*:R_ `prr|7: XA<7^FR>3`o?"9W{? [<3]_S]_ :_-f gFrq%ȁ=@j`_KǾك! 5 ً螗qy*o^Ye9;y<3xs>o%O2 Pس G_參K! إ+ pAϖ sL$`/}Y@G  '/\೿?ў{tAe, >`/\?yA.?ɞLs迊}`w|_1K,\?+^ enj!l[r])Ik4,۶zw^ԬdV*>WSOZ\m +זb{)7ҚQ\btƮ]cW#d64(d"n4VɌr*ɩ6 ˩Drݛ!.RxZyƞǝ.>E1$f,]CyK{saMqjLةf4PúQo'Qz5xgsucavosZ^ܼ]eerQϾ?fT50`咜9V2[ysPTs E|_#.+R(J;S3>uN>᰼ 8?u'}ꐸ6:y]w(D> JWDVm kqQv}/yM›.dL"4䳐=|h  3z A':?g>kW [G8E|I;Z|^]&\CEsR%g9x}W\pe_J]዇FL}q][|Kh]ECYيtlĿ]$Z~)*ELUÓyp<ɥ^]vq2784wJ0QNT3 4[a2|Y2eA>~"'WL?i>cJ{-'I/g3Az6aPfe}} e_]J"dT!HB7l|o[+3J1Bj梸@0?-B@ P()CߡK2}صYs٠ƌJ5ns,TϏSnCLM5:C{$ :sꛆwiiJ|4 CvqьG 5|&7~wTK˒15-Ÿ- [M<ĵ&v~Wwc* RτҊ[2P`"X9^2dE{'" }6ސ5C(|"n/0R_UK's*o_k&AE{ NvzkH0*;*Ȯkl˞מ~e$iZR񡒖ti--(sj.8ظ|QCdm%\Vnw$oAT(m8?~>7T.x5۴Yv&k/Iq ˈb^)\#MMLѭQڴOr@v onl#8}LԸ| ‡.y7&aXd뢢_OŇEc ,}d29θ{z)0v;(9eހ.S(@;$g8ba wk{:k4-N@'t̷:|1kibP=/~.AK(chpaLj{e3mӪRDhU{D`_EK=WM񃑇Q}[G#̔-sN+2㧧s9-YYacu"B)aGһGob̤dV]\?\#HN´?"f1ֆ\Y?楇><QV[ע[u;ո7G~f(L.YD?x}kFB*L·ˮ եrt$9i8sl8WJH1g6מ49 C~(p1jWd)WWD}J nݟ$2~W,?m0ѮL ՚lF e6ܛd=D4#qAl +uOXOm+ E!usiv#k}4 <(cIKb2x K @091*K#"r4U$ţRW6u\D̗G| [Mh'kȀ:`m#<%~ Lf/7*+*Xaw薀Iz`RҜ#r҃TXܹKHLx>3H35P""^xU2Eԫeh`t 4} q.BԫlFtڔ0;-&h*œq;=+/y"2bt-T|u&ӫEP0v:=!]JwRz-e V;5+&1񲝳!À_Zp\ukb+4Ss?gW)ivɉ.3FRR HJ~iR>Ј{(DSY`-yd)"aB8XT~,<{DPv8J> 9[evV*ʹ\(Tn϶KP~ TTñ-**H47A Yc<ؿ%]{.f|tF4LXbK׸m`-q\qPijc׽VCXǃ3@Ŷqr-~OiL-i?@?SD6V)gQ4 Vo[@JGsͧRk;I݃F Nq=J7AZ=dHot'Mt= |U5R2'gMRMiLK^oRu n $_ N$#~SE/ GJOH().ENޗۋ{t>>ꓬQ~q$pkEgd@k/xbjEk_Wsx]hQE3Cå~PC%.p7HQόU +̝~փ[]1\sCw>Enrid``,᩠ľDMf d(r4ᑕDL)}&m5F9Mj#׮31)3Iq_[3:%QKJWz 8 mz{\jm+6f-L2%!c慝}DZe% S@W"~D.Tӎ O昗㗦$6)EwKtx$8~Ry Ww^f bu6UG*DH8M<顣KLK/_zdhBh,>T^k]}˜\*;Y+*52گ$=<̓<Ƭ buկ%0CYA sMߘ5ɰcJ]+bI&iqՓ+Ϸ_:hDZl_|1FqHTC yrpol ق8OE /C;1mڝ'0)f.X E[>_W}[||Y:5)!'ƮK-<{[c/E#-,a|3it빲glO?$CAեp}=\i>(©U%rt1D;ܘ>4tTiSW}Om\ .Ƹŋ/.%)Q=Q> kj{= D1ywlNxo;Kћ lix*&T뤊e&Z8HiT3FiYyʼn#M8( LOd\e27Ʋ ZDcIy ǡ$Z).mU.Lɟ^Fpnuh;00d6mӲ‡Y|`" 9$k4$(^'>!S|o|{GVfA 6 lԘ 47[##fE-!n8G+'u&(õ9xDQV&U~zt6$Nv` n5)-os sͽ<$+4Ki`F_)qջœ=~ɥTb3Օȗ,.;F9GYM<_XY0'+cVH."_Wj|]m]P8ΘFw"-z q*DeSӳW,fn1])>CuziߜxRgR3{wI5tJvDK o*o~#ɗq'.ѽ` !RCJ a8^edria/"&ېrE{J1!ڱ&l ~޸wj7~/^,d_m .? t6_8}:JC%yЂB.95&v G![|#S!Z\Ieʧ\c:ELQﹰP1gn^AC\a3]IP?cP pݍt3V BW&;et.f o.2]yblB}2#jͽ3.wI]|qɫ[U[z8ڙ_+M ɛgR"h j+#dv氟N5U'XtDxޗ0&c&s[O*NӬz Q9<2$'UՉ08{ڨUfN[6CQ;m4C.jlhPtB~E=:sHSmh1|kkW_mGr"h K//tJw\0 EvZP?~Sm#z*'cLu%Ƕ7vJ֡wթdWRj6|:Hnz'NW¢ie;&~sJӜ:8JmWN,G{_!eb\.X%uSQVc|h/%6*.?|_HAy'MxѸnzӇgǹQmJv#پЎMDR.ӷƬfDeR»$<|~_ji)'hDb=(/ҙࣜ_<ޯZm_Ġ׍#5b?yo!p/jjʇ^h(V(. !DÀg[rkc!M[|o\ ^0{L?-''ީ"i@D[xc΀zYG~&7w΋YiRYnyeKyjO[<` {#|+$$]! EYS2{4658:ÿ@9k-]jA^M{?ީA&'5\9fxfKDj 9 qwE)nnSMO΄\ZK-^Q DLxWߚ=HͬE+BD([*qc3(ɒ*1H#]&Za5T:|`w`sW+vIي;} z.`ƑZOl}mA>I" HB12%pI4f24~N<;ΏxoNm: 5zzxĤe¼UmiA-kMliZ-??x}K +5V4)X/Fl~[dKx"^vkq[ U ļU-'/&rf:J1Yauz:{|-DdU:wyWNc}/A,-UpG`uGժG~l4+b!knO_03hMo7 tՂjWUJڸ'Mt0( ,X,y,Թxezc4D3UI3,~j9i{>U{5?FpTJB%1{L {lL"ႈ'խƓݡLV) Knؒ֗:ǿ#`|~pU@Gw*ȭhl PS8fyW o=1O{G: 7:ԼR7l(JZ .\q2-I衄!I(I.'؉:8H(+"KMD6fdOw:Xcʅo?0'~_$@}u^M SYBnG/CI0r *d@ hx0@p+/pVxqфýR_+c.E_U/ }h^?^thW2 ˇ g%Xb?dmD"8:>WJEǰ?Q)sG~do':h}_rgJ#/s?)0&/Tq0uŇԭZŜcq?ϛdcN~]:(kf:Xem\XBַh jz;ff%UIs{JF/oS==a>S&96<9E32/U H{ α/h| )uڱ~6$ L8"g\^%;7]jQ ]Bbq; 8||UZBt}oe9sp0MԞǠe?$] >/)3@A1j_,#OB+~1 5Jzqwe^E|ļGcH3CA˭v7r>'*I7L"(5l:\ǰCL B^dQOQw&&Y%՝Su}@[S>p/BTQ9t3=t\  v`ؗ‚PjkA,h Xx8ijTMWM9);w3Z1`UlGM$!M )xwkfMA$-]A!pﰷM] WsCy icd&'̗R]x}|YJ9堖ǫ 1kiPȜu5̻I  Uqw%AL;':!d_d7~zfIM=ѪtSc&J8Ɍ;h A,&fY#'|sO08QXK"c59wҳg n\VE+b.U'O_TqlMc}3&U"-g(0w%i:9F_K|C fH @mUD8w^Cyu͋=QmiqC.fƏ2X˲66.1nxjpƌ\-Y:6L'v*XUbz\+G=;R"x1 ITm 5qgI$4(n~u u-o"QvR=*\·&O!7iOR$y-肽{~{}ϻ |i.ypH(>uie-+BAaUWG{Ue`JkWݠxni3,~8Ple]BV{mӽeJxa3}耮ga!yRcg r!EՙolaDNCaDxmls^_QIs_Z ޣ^̿" ۉ"x*:/;AIQ{]tLs{kfA{-P)~kZ~PXMWj]o}:|ePvw KKT/ _Lmg794t1`>3Gz C#Jr |h߶t{6&*!n(9DzXDچNEuc?wƱ#*:ߔj7QHfd9t;w7vc!6M~!_(3Hʶ VP *Ry%sa1g8.YloDXWBH0x8ͣ{1*&{VQemM쎺)j^؆D퐘 bK]`]xQk"N˪~Oe !&+:[e:k!|#G$Sb?ʞ[S%lGw0mrn~#`;1s)ٻnɥR+%75t*@  ,)MRwd wv)(jNG&=M´Z%[[RU!|3jU$L|A+#=m/C^tS10uQ^PH烝 ɏ.]~Np.p3vk+{tnk†i^EVjtc=,b4JSe޽Ǚ?VW9ص ϓih}EFv)S֞uӒU֙7+B+ea|;6&7F7O17J)5"~?|[1aCDn' E[1fVi*uŰ~I17!oIͻ&rLI1څcmiTd$ iWs6(M%gފzJ-6V̞b/ݘ*738ZފQڽR/6sip b mκP endstream endobj 333 0 obj << /Length1 1852 /Length2 11995 /Length3 0 /Length 13149 /Filter /FlateDecode >> stream xڍePnh! A{p $e9{ェ{*1u̵\jV` &TbgqqPSk Qun "$]W95PPpwsyyll  =@Ve B- vvB^#Βg:@ 4w(Cl-`K?%l!gVVOOOsG7=h݀@+#TƂB в[C<]Wdtvh+TN+p,-w@N&[Z͝AN6k*0̝4wp{-^nWN|n gY(zNV`GG ~R W{}N`O' kcX;j;\܁RǼP!n666>Ne3O'}1 k_7s  ;; d Xm@N(T5¯ ʏ?* OW̪$uJH\fNN7'/UAW5Sa@z U@?27bf|YU_eɸ;8+or;UPn @+C_wA ry@K?Y=s9n?^3;.*?]ߎN`?`j$nn/6Z1 yMNq<V?L"~^?jZq,c=տ ;_rq86\VBW^ζ7x_ 2wWׅ`Wd5j_ٺ Rsp^nLlZO+;'_ <_z9^_gk#KwW~5DY[ Ն~'dMg]rmw@LpOZݑ[x=iGhMRo{{4MИkCY$(<LƬ%dݩ@· γO֫le4|~O}Gl9V;(,uE% ι N B#i,g&s>kZn]TDo`qFh|%S|Kc6rY6F)F:0T!dsp]oc EC4sfu>X b\g?|hwrxvgzeIbM)O>__]V)Uoĩ׾f@Ow ” L,F^ꡄ\.#*6 (dnz!eg|>d 8Mv ? +`02x kމ)X}j9S86-+x~gX{"t(r7kaܔKr%ǭϺ#dP;PxXXџM@*=Vd82N+u8w{IdlobXMM 84|Y%#jXZga,^HsF-3Hlp7iɸQnEaڈA4R 3GPY48 {sdmaj;6:{̯XLcG(֜cM0owɎx7zh'o\+qtzt8:i攺ӹAtAJNG[7W;Y ̢z"ݮ' +Ķ&5 NiPzB_;%|+Kw0nB{-PQ|v1_gagmsb%EJ IuNqEFVd$I_?EKP~?KBK,/[F8U2G `ρ-9 /rh[߼/5;21#KEp̸H=N+-$|)ˡ!c)|>gBKrx Cb Owl^V9UyYeLe]S<i Ϸih*`-t] <ے^ Kchz6mMzд˝>v?a%^~7Y JYXЖ;Gn` Õ볷ߔ(a=UB69% #R`<)gؖ~2&܋_j}cjہbbͅ)UT}׿tk'{ >Ff^9WѬ+, "{TN H Z0f")]꙯8ɤ3Q6ZnÈ?1e6NeNgCKH_+C|=T3|:FCgȓٺ$,R|xnQW(` /©Ys2c=&Xw}dEg4]e;[nyc$+gxcWaiL#Q"d(N{S3+uB4@r?eQ+g<#bz8ܥX~'c*QJCgeaqۘĒpm$pѺ{$Grh/ԣzɡpTC;2&V tpBx*˔L9(tc!71>緺";vf$*4`QE7VT` %uw@e6&4Jh蓙  oҧK1߇!x\ƋY G#-\Wph\1Op[LE55AS 3/쩼#Z"ٙmzc<)#U<"W. N{<%f&٥A@ɑӲI☥k6kSxCuzD.IkUib*8d ϻI"+lXAE gs_vrD% cؖ![XbOs.pf֪ :j͇sP`o\W,C }CX\2I.Dwr9=R.e_4҇鋂W]  ﰙڋ!~$)E×_G-ݑqa=FsN*  O2uvi$_7u$sns:iewWݛe :#Y|]OV DqEq),wcuX[6MַW 8=KK֯Rܻ0>B, 4E䞓s ~^8fn![s߷ H~*O2'TU~8k7Ǜu ݚ}Wacj.ta^3t6ǗĢh^@" [AMO]LPth2"SC tȞڷ٧\i}Lٛ}ࢱ>c/B]>BAbiI[G6syUY, ZgbrF|IPOʥqDv| QO׀w~8jPpKJ\7BjDrJeQtm;~y#X۹5Lf߻JLU6N|Ce_Hφ yc'Dg_ Jf*nxS[jMR&{:e' ^Lכ` MН]wsvLMPI)Lʵ(}A<զ:+‘RlC6lX3 U~ hs^HS*{/h?cV+6e$pЋcnܝX,T'1i.hY1P8 \(Ńlw7KDƶAYd+ z~' ZydOmۢC.ve(O2gjs qOtVC#7,? Zs%Z RQhF֤}I,1a~H]s2u/yr?vK.01vQ+ {>_#qa8 2z ABW`I nsY*zX5vSIN!ӔP$~ >2[\7dr [_r߿Qg0Vh.]Y2Ww/Pp6] `F%C64cI%U{lSpG恥=KVW2mplbX$SV~E14n(lzޢy 3̃#l=dհOlOPxܕggN=T dt*f%f U_f].p \N|'dTR~veљ\HfkV̒w7zټL잋Kpy#}^N{_y?1C\1k Fn4څ}]XUB物I(-5L m9X[.$qzڼA03+Bu "up+:QCeE01c8hl@`J3?=+ym 6:BP"Iፁ@VjfP [Qyak|W+žfh x-?`%,fyɯq-Qu_]UdPIqxv(}poX`K=Rz*C1QAzy+[X{d&a C5M0:G>MRZWs=<QfIaHs$-G Iu|/27e\_p [ңǓ!9l0gsWpʲ?HM7'c.GB߭圖ʕ1 KJH;>ěD_Ygsp0H%İYM<|,KVumG☕V Ts|5 !<4e^~&)2Q5в:]dD*OS^o~X'S?Og}Y"C<<cZT߉.Ƀ/#AH 8녩qƁI:㧶)aqP/Z5"oh0u+$Gbh8%|kiqb-fESKZFڳe7 2X\5YanSFbSPiPX1q 7?V@Ā/i +PgC;HM8TӍPXŠR㔮'uqz%d'XG}=䦂~~KdX#[CRC `a`e,ݩ SO{'8_.D} cߵ:j\dsLe{[AC\GOOԥJ%'k>3Dg]Yeӓq8`)s!6W>!(xl9 `?+6Lc)cėQHIݭ{ۋ&3.R], [#he~HQp,85{sC1^nV?F5u|B񝨉Y~}d8#B(5k"D,}[uw 5{~nM0 bkK&vJ\T>5 u6,&̏98U}t>$Ъ'}\/Z "S^,/n}0VԀHU,/ M甦OJѮGfaǕޮMFS`yzPN;5ZΞ=`q)-yC0PօM DB9Sp;(Z_jcJjnP$6-s]nR!?*vRo딂 +EcZV3kD4#@vvljVaL|3/E.Hw`̟-(y~wzy\-v'~EzP}[w"0—+rng'wiEѤHcAM06r(W,aF"C4WaQE]JKc br熸#Iϸk*FLGus3kW*PX'ѕɤ22n3_K{ +GX hб"|}]w2$7j! -z!77|]A_?tm |4_>}+EW޴Yh9A RxD MNI%3ؔI`>-uXA;U!y0{X]\4$N:d^!LDl YL~hA_>/Mn.T("&1$gQ?˿"5Bك2l 2i(wW8Yes;us5dq.TFKY@T̅Zf6Eg4I:=NkܿJZWmiwveBY $ 3`S[w~zҐ"do~ɽ%E+nw p:R"5'O1jWF^\QGw&Vuk{ Bg_2lHliYhVcS'PR 5}AҊ /~XyJ4,:c줄vJ#W~5槉g|CJWU&S^|͓9>G ٨~v(. asچJ e-,m™ъP_U=x6(  FٖN+9fɼe>Q%VK_s~X/v?P z HԸ #_`b(h&CAY?`UyY%z&^{!n,`gcxBm\D#! Z2\қ:p[J-ADŽ%?9jUVFgIP="~ǯ}hG#?ر"9=镵oߵ8}uJ (([~}ӑ@X:%I3 ۍD/ zpe qJ j|~^K+޲4>h [*-/ɮhҌȇhG0-^>v4KpRtuuib]2%RDtGPITSI<_u=6vW>[n3w?3?!\K򫶢cVf"Iqrh?՝P'kN&F[QpObY6xC:d ub\- -y[IQ vbxCsN=7QI0"na ־+} %ʦ+=1e;e<+_.*ZRji|k-4tyoxZ5JȰdo̱ R2^dX)YC}pKD1)[$lYj,T!yE".2k="@3iݛ魴[)N^KɈ׺mG&Q=gk\\8|Ix% wmxԜ?IqM~.b#6gWX&OU7u<}u#vä,k\.' PA1᧯i{0&07xOKi%LmIa72,")bKf s@Woe~N_Th޾gP==ry 5(N<*_s)wV?Ƭ=Oh*hwC\:IQ(._zs$=КNe4:܆e<\VQCT2J8J7F `U2SR NzB,8g{a s'Twhn66Jagq%QqR7 %';J,zs.GXuA6"<a|eeɆvE'W?xL4q/Oܨ.pדeZ7Uu@IjbAJMFvo2ey-R8, |I[-{U+^iyc= Iy: j6OܥMc̢ͽ:{\wrB\ej//4ת{8DOXR;/z֟& eC%l%֥,Q9zҔ}+ٌv6]b4kݢ#¾rR /՟o0>0l~YmVnvYKK&сYW;q:"ʏAJKX Ou@Kh7*xm#\|~{.(uqSgzwȍx=*FxehiŠj.%~7Eދ2U7XT,*A5K֖.\H$ `Fa6%Qf:_hN.Nyo$Y9*h=Y9'@SCsq5.QXJ Q/-r Ǜ:Ξ@rlPY;~,n!?aIFC*'?y%-iҨ%΄ЏtdP9ƑDZ𹾲F‏|BǼ3/GB\X63?>Nk+tF.|&Y! af@ /Z>=7KܚBqYcT4<}muWv5;30?r۵[ҬFa1&h<3 ,QߴTf Y1c(.0\/onEbBIMCAx8kkGcC$!E ˙fvBvciOs j+Uu([ϭpԃ<$H&1I.͌&Ua@0Q UUʏs*%Y2^gObR/9l}l'U+6rO6Q j3ԡ,?*LDj ]x8QϞw>Ӕ{y5h^9^ϑ$1*YUw*4Ix|^Rزzu[ՠ"s~%C*ZV^ʎ|YɅrJdjp endstream endobj 335 0 obj << /Length1 1632 /Length2 3604 /Length3 0 /Length 4620 /Filter /FlateDecode >> stream xڍv 4T}ilJWe !ʾ˾S&cf*K( -*BȒT,ٷR{y>) +[E4$H%gagDZ @t"Kr4!>ZI) RUy@P/C2Up`J&4H%xyӡ<>YTW?TC,0toʈ[2 !MS4%/ML:$ހ H Xo8  [2$  0H8 @[s~0P~@*! {=bɾ )@"X+љtC­b42O`t `c `GR :MF _ـ#$: ^> b@ Aۓ~ D $yt@@L7|=] P"P2Cm<`4?Щ 04OD8x^wtH `& ֟ܡ ÑIG 77J]]2VD(2RTUпXa?@4!ɀb)*w#dhoA@!TX^ ߎG_2 G%Z@{ˠC CL A\ G`WkB@\!y$fH`8+뽱?<#HFXYE$D.t{РPwh@’q$C*C@RQq scL\PO֏TǬ62B$ =,HU~/2 w? @(poBP(ԪC# GBE-!906_2T`4_xBA&&cFY9_G,@q]?vq@:\Ose}#NՋ+>n/qډ9:MasH!OG9My)iXRy>n)]VGJ\,q[\,:yt^TkN]m8Z׌Ry_ߓ0*61M1[L82V*jtI &Ȇ/EzҞ[%(?0,FQKݽWu^T}AoY UMcH'$+zD<6XQ3*aK4Ģۄ{E'{Vcw{KFVN0}[ǡ|I}fHԅӑ+~^aclx4\eށ6Za1hmu[k#T6xj)aKB1a0;[ئi9xfWW"ߢ qWRz9 ,MW4HS0o%2|RZ۞g#:uI'g.^l(Khd?0UnUT(3m:!af=aor-1"JHgyӏ"RG0"`3DBp~ێE !<}@PPh>zaTЙԶ ӵ7ف~n"fz'r&EDY!^M$   WpHPv-/RăI˭KWGy/V>;7N(Ȳ*2[viTO _"/pPjŸ#A%oy_D@0ڃV|Rz"ӓ+!FϒŚDջ˪"|s-ۑ9}yzcbJ*9v0*~.:"b3lwOSDJ=)vAjbjg[eZX/~)=HWRm=2q;I-\$/!M΍u喙m5NS,8d l%EƠj}' <^HCcPA>0UYZvi <@I9톿}_mQYΧB-]f_(RdϖnWa7Ez墅'ߍ4R7.7D7+vGq`WmlV%a۟%j,ۗ{*ݘ攕_vlk.i,v֐P`oϺ-fbU}>CfWx]p8Qv^%|TX4rhlJH|B>q&;V8䵖ZFnCq g)I/ohlO QI$=!-,z7NABQ2T=:9]K2 *2\}8$IτN(E`ki7ur[ 5i! 9d!9 e拼~z|ٹ0^􍉗Q 3bMEƮ=LvfY7vʅk(JR0צODyYIE%WM#wLs e Uxգȏck=/R6 6O.),o!9TMgCt'. Mn@/<-T,#._/M>~X@_5? J95(s&]X[4mou;1Ŭ7V)e 7Z/?q8GΐzuvI2mQvtX# Mi U$lʬyd̲]Oʎz_\F%%tk3\òi'ihíRkѓR3jRӂjnsF&J`IBiM;6es˷۬ϛpUu7v?+"[zʫ|t 9o !!2R**((+B*x,Gp_G,^o١ס&&z6/rxN`|O]^c,YZ{Ė26{g/f)~fvqUiD-AoVOMrʹ\z'* rw=n<$fo^h*AH-6Yٻd)Us]h|vtf>##$9cf1W$ jZn܉~$wxAf[Ĉzmif4s;+bq\> stream xڍt 8m~YK?J23,Y5!&cfbb%RdmG6v-}{, Ϲy9}qQ $YT8efc @ rP< Y@ê""ͦ xf8,`L0SQBy(T"!|(L0aA")>$ю/ `jj*2;ဎ7H@#X Ai'"D$›(#x$O $_l7 #ɱ6hO5Ν ̀A#A,AƢ@@;62, ''A5&Wv"4v'Dl1 `a`*G',jqx/A;#KAkW{D$'hv4)cQp DdݮOM@~ެ Xv(2bEA#_$JP(TU >l ;NضAHiM!hwDD@Cv;Xa0F7efb#=w&/ C߹_5\gǿ}8 HV We55 I""8@g!SRsh?w*A/Y;!?}og$߂ ̎[rhL/MdMf8`K=\Y3&{kDB@=F4hsG?Ͷ+AcA8~SYm^wH ͿO"qWR"J-" Q0H]#n_ Al~"5TiF.@1O4%O;*`Q|V/>kwI,O˜3rlmWb *St2tu?1:J\n[~`kZy|:i߳M>g?:LYĵ|/yU2s-咤~A谈3&mĠ&zͅӅ7b2byuH1w(1,;#P*}rN|97πY%&yi+-d|DFQXҥotܷNMD?^u1<6ix-کP/I:AXcA1gL_G#752l܏=sҺM`)lݠaO $lLpʋ e(sTX;X[H {Icn}Pgh;:l>veG$M=+~=65N/ʾ>E gfpgaZ"xܓ4-V&w޿]}iְ?bu|#]zQiZtG%g]?KU o? pfQ}7GgwhkDZ,0V9l餠T f!綮fȃubt\ԨV>Wc֋>i4'm=E nPs^]xbv9+a5 .زl v ffU%UyRʢ 萖8cpZwJl7‘JkN=uʮo1(ދaњSP E_>i%9El!4vS^&n^sے'V~3Jw/*U񖾟o~j(5ZqCP?y׻l;xsMN+{Y73mnM/ǕcՁ:g ow^pި,*Liaukk<|*rO˷lgzt;tO)-|XL?H,FD/M.=1Cd٘LBj(:ܘYѵjGH~ F=Z,֬K3H+ %efN淎+N~q(!?iZtRN>7nƙmT95`>*+<+k&n{WAjǒ:!"*OJ6;еEE$ce +wgV+tz9^ $!G[Ͼ@nKz` :1lw8H{8(,aX{jȍ29֛QF7q#& wLթ"Eb΅@]F(}艻KG\npɌb?L(=¯eQuPkZ+ǜݚ2u֧Ŏ\Ym4~ "=A> Pn\?(Z1$2"youvO/rG 4uU 2To%NhYen{xK 'PGy_XKmk\P<_[J uYɺ Ax#M/|/fLɳY! x昮KXDe!d=^lE_h_en EIӯi%ؚFVE-5yU M hk ޸0tm=&U.E,u`q b9+uA]ˆݳr+#j_ qAH[q,qrؙU|˔H-Dzrʽ}Zݢug$?6ܴrd}!0 oY;B0W˘Z9sdptZ[ .4ʵMy0A;{zib^Ѫ'TW$B,&r/_ڳ"(tv힞˺: O*";^%tm:ފs ~H2,ROl䫏 P^S,=>\:7eu]=Fʙ ]CN+r*;ū\oDl5R *1:[c"¹CC ΟfFM̆; K>fE=GL5.+⍶Ku\Ja<(Z`c?̬v*J%qKspP^6#-=KSU"-OZJM6[EA'y~D@;/`m8X:1+rU.6QnTnN⾌[K.<2^},qW8V 6τDŒkzȜEHO%ښ9*k=U9f*~f]-lQƳG'ֶd?eP##)QkWQ5pI.PGVz6y=(1,*I(5_q(C%BS&1h$x%~<ЁziCa{r߹.UȄJ~'~a<*Hah~H|ڀg ۸5z[#!N׋ޮo>$v%LZQISD{ș*+ vփ}3C Rnt ~*aM!3tx'm$CYN G"+Y] 윬An~ IQ;I8)n7BB Fk@3Fֻ/ʇ,l6չos$;a-#yɛ`C([kMpA{Aq<'S{\ U re)"'$AZJW+}N=T[ Ї~q0e% p(w[%6u~=|)%>[2ƫV#7 rt u?: (ϊe鞽k-PK|N]fP CS |~(p1W&#TFPښgŻRCxSr56/,y˔ !2,Z>-lU;lO+\~$frvu9f+ђVs#fCaL[R{Ot‹2!y7_m\}? 묎 endstream endobj 339 0 obj << /Length1 2563 /Length2 16354 /Length3 0 /Length 17851 /Filter /FlateDecode >> stream xڌP-w[pNN$'=Kngf^սEZP+ Emm@tL\aeeN## =##3"9 Bhnk/a}6dlmNV&'.&v.FF3##(:p>8d6@GD a[;7sS38|PQ89i2Z̍ l2 358@r/TGL!L ### h1vfK `.enAp4p@N@/ !21͍@C `h7=&>_ePR,LwȄl]tt,,6Vf'N;70O,%lLl nS4K@՟fdc4b^LۊDS% ͭ^Y'xelG`UՀ K%@31探@cys_7Ĭm#n8/|6Q}1}88!2׈ >Dc_ `M&  ? bg0AL? $ V A8?]S p`bG4o?f{,^ZY;s~G\p &[l`?r_s)Vp̀6sYY 'Oಭ~9wFV |kedm3W7O`bbWfG aZ2ٲo܁f''plA@c͂ LTE6#+埰ג23f95^pY }8YRp̿wp4uwor_v//܁g_/]FsF܁Ձ-.t;c;jtNp  ]+["T7K$/Gp!Mq Oz1;͈ }yG5Dv=_=U,!%)8Ps]z\kzGvv+>I!=OEDh}6̘'{#y6ss;9D28%Cs9a}Tٱ@sdCh?Qoޣ bw#5=ĂMgι-C>)3П\ٺksz#J&mu &SYą>d~0Vg^/`ʿ8#EgH1 ڎ{y>y`T(Chs*&<D6@(^cٳb 1}iJ4Rd]R$%/y%d$S"<(|)oL}[ٹm&#'˳2L89m7^%[E zDAsjҪ`ӵuD4, zKBwPηaFU )n¼E'xSZ sJJPn/KuʯrNN ^5P-NӬ}\C ~uStNUT b_]$KQ?E'A^"6F `^>H *.v'nAbR>p& n)xuwvo̤-@ o&X"AkGγ݉^,ƞtCI&65xcI ʞsƓ+Dv0Zc ,bA}]K}7>0$A,x F\[ۗ{ك _ތ/c>,qy<`d6[׶P_&qD˕XІ''ȧB. S&=zMf#/5y'V>i3-DH lF¼f͓Rx{bFH oMt` W N@uz9wyfܙvc@:bpwچ& QYwy;M6(a3 U)Ed^ެeI/DfG~VLA4Xm|`rwaS{L#E$SLZ=Q\[O,mҟط3 tF80gOEqãG:<>JEhttf @GyyX 212YEVZK?r!IP-͐Iw " `pe#rqV^c"? `f[T:EN~u9@UK&Qo ;MYh̞'[fH )] M?YEHSsQٟp`Ryv5bPjj! c!eإ/[LDӂ5Ӟ 3D0/\l$uXR>k)#bAB)vqXX<}Y̾R!CzIgAޕl`\ҏwf3.u=Wl L5xBkVSy~S%'Y%t6պ`VF?hZژIP4zn|`?cIPcEH-0{nU\F=nQ^X@h!rD ŜmZX<~M޶j:Y^vrpHu-{J_V*JjS0b 8M7Eo#hߛp2wsnptM F=ka\ւb}^E1 @dzPCU!ҷNms,#!$uS7i[s[3w72K <0.V\cI L(ïcL _WZ@ڻeܓTQqVTudӨ:YA/V(έ|^~YU*OJ)KESpȢBik |!d=>۠9|w:'zQ8ʩAϯw b. [̍Y|N0Q/rF&1^fԬ8I&?LI Wd #꼼 xX"n/KžU-%$1uiW _Yn)3 VZYn" !):#|#/K^Jy>}:⒝A;wWDxZr]$U0%?B$*+~CjjBTRtVA/ǎYG˒Ћo2UdI\gx<%@@/# ;B%CMaEMi&AZؕw9qqLk?m~ٗC{Fm pe_/}j/3H>4.wVLyw9Tg#zQ#'W0;8\cy<A(뛜&.lnRLG]Vd[zzX}mЫ@*CA8 icQ|cYKx:f3!\q[?@|1 OBqI\5zD$mj@֣eRcE7"aeueC9@ssxA0cSNw YO]p떡DA$Xf' U*M0RYnNz҉&M'+W̐3SIn3lC.iX^ԛNSL'KM.ݠ4.cH5%O|Z]G<ũʣ>@1B[=Kյޯ HXbCd}3T1h Cca嵴6 ՛ z$#۔X6ҾGGsc55ᡶ"GbtkBNEZ+ѡ0̇{1X!a'nP n[x-IދA!r/yv֟ FC U2k(|Isj 2)] o.S `ߐt*g˼a[}Vf&+Ao:%Ez$,s׼4oc )JGrC-Rz<Ԩ`B&zapa ߍu&q$3~ ӟ6{Nhx$y&M CDg[@&^YyA^VII6l6aZvfͺњP}f!/)TYDi^L}8`ݭ}(!kGN~ozѻ6[ASMs+eqg9&6#* ) rA +{=+KDeun)gBk^= [Q \<1(7'S+$3'az7+BӦaЙ5B5KS ibFC!:)4DVZ9Iv8LlŘ|ƷJ_. vf8`HIhqKeUkAɄ vcHG4QhXyq1krgD;=dgyLx ݛ"b%( o4 Ȑ?+SJ9qOD4eF*2'nj:ֶN<4 'QR@]ӿ*1VtP)Uv"BkW<2V"gfRXĝّӧu {0l?/c5piuOtkÉb ֙^HaETx{ׁL {T5Q[m?f[iR*t *o%TnU_*+h1\;]C(S-zy|JjN[Fmkb5)$mNtU2o=anY<VA㡩I$70;k-").Hi醫@n `K_+$4fOps\to .!GAJvpxdz{)AQ$OheÇ Nj'>|+|"߄<{Mм#S)WlBW4GhSWºѽgVW{E5{ƫ{sxDŽ;DIeT$z]K *a)TU6T[\HշMM v[Bv71|"'&!K7˖-e#@q9KYI[r?Ȫ oL<w!h%E3X #^]yt{4Mt7.R%yŏ j4 ЖBgK8Z^[*;nnдgeUgü A'ӅekʋPH44~@V#I _/uWݧ_:%ix7N8wp=]S.:-^|BsIBi(A]NR)[YPZqؾ2$\p\~䀘idvl}8"f+ R ʏ@q#R#W>׋oIv"XG|etv2r=qΑaQWרmy>t(ҥ4WW.ˑǻw6tdZȵwGiѓcA4 ? 9yK5c|#sޅ{RDG;!c'" :b7E,*!s$9<"O^#\cX qK !'GeOΦW/*π]}+Ű5y͈FGnnKeНv6oچe'}ΥIIÖtts mD{UgZdQ?:{Rk\wTOİkaw lm2~+ uX c8.836oﲲx TŜG:#Ғ6^6V;w)jT!YگXC)Sc)En!J.T1f.!Z414NraIQTHN؆UnLH`,>AD޸qx0BtP>L%2N;}bt]F~'\PT8^n^Ր"1]vd1~:tB.KXND]#W;!.& A|>:x +nw;Sf[ Bfu9-u/ZYmV\#Q;Kl4ޡl5З>x]lo.[~ehDL,A5ǵX岦UK {7{([x|W'x#jPhocѨB 4߮ip݀lfAKsh34to?"0`Hjq: QOvdwmʳߜާ'gc}f_@*J=vLBGm p Gic'" 6ovNʰOwExvH1A_ )S"141hA(xQUWč_`k8PFY6^~!O+í}3ER]/. %# 2uΨO礢rag|r!a`M0×/d*Ul*@/Lww\djXP5_#g{K q3p 2(~ޡ]jeVӟDCkKcW*ΧieD$u.\rjV^Z%ű5x*Sa9K9:jȏ:fT,C"Տc$fYbkQf́ck"q4 MI =ˡrMr%sjHL d]rG#?i~J_r;5?f%HڢdQ9Q|g2_~FX^ F E)}tu($$2P) |6U"geSGdkaW98u(,5iUJ$-7 i3Q?aH'm'CUE経WoRg͘cۙMZ*"X' ܂S,>El8/m }Pv![d:щ`OWIUl~9eBkwAy8AK Vt$< Nn7]KaIMv&i/l _Њ7H%s|7ʹpx/i8UنL %eHzN{k{S 8wS˶جz|:՘bj،徬0jeJaiVN6([ U4yXޮA^ ^/6So7b:Гo~,,UIG䏵˚5t.w-n@hٸ1H`o?% e;2# Xv$J1q.v`2Sn<djuV59ro?}iW/>JLNJeGଯMwNfJZWPJ&/*aז(x,WOE_$ұ_D'Ak%VcV{/d>qrװ38œM-9(vqYB~tx&`I!K?|ۏ8{8NT^J͊h Asekl7Zhܧ uy52|'TG'Wgܷsیd!FTϓ13I]uq~{@ Xx3R "mќ(JqG>a$OJ\ghc*㌾N`;ϛ}bʾXp% ~dܨx|D;~܌YNWڣVߔl8b>z8,kX_&N[5ϻ[/kf&O}-}%Lg]Cnć~Wh67&zm*)Cz]MǒP6#RC[{q3bQEf4&(Bkj6EG Y+_?JG)#5jLylZW+fξW?~]=7wɗنX({}F ε|bۛ#BE#?Z+ķiؗ/]'&x{ !%U7edo%XɌ >XlunDwK k♤l*p ~ TЬ^NХk=kZO EGseIW*Oe7p\?%pIy?==^dfs [qX殾fyXǕU d-KKH$;fM6a>8*3!jM|=lirEB;M=Ne|JMC9_7?l ȧa$zFMRIsl*WpZ.cgyu&wF^MlcMFYEHs;1JapuZ̫!nµ'ha~Xˬ?5ٿWυ&ɡCp-|_} ;RANuW1B?]0W$žY *űIgla& JTg|¾[N}H}jYo[{AU5>>_ɼ }N>7+$-κG.Ѥ_7H7}Yx|xgogҎM=m0dVݝ)xºͱV|{%L)V̴Û<(9SM&؂ ggz{{d-F?MρXPXB Pb3p'$2Ь6}{TDܮY5eQkYt7pnG ]3{Tz| ͣ]J:vIxWќ*TÙ!$!g}_4/u/3X&+ؒZ5C\j 'v-&W쒽8[tAq5s#D7}k#pFG\8KXR&+T(At\S%a%Z`wun tc1Wx0ʾx"KEe9N+ /d5Nmixδ͙JsswOEwQƠ"yC|еR񌻏5""7HH26~Hx>G ɱp/wX2%$<F-Ì/S;kuEQߨrgǞ琣YU:cqQi :*t6 }՝Tc4/n0r1Q9ۍ dPo+{=|t7nUGeMO9Ay}5bm{'~ 3a38 L;}5kPF|t҆7AsK*WÂ%ǚ9I:: /I%LcwBuvAG8¯'OqAԦE@h/eWY8s 33Nʼ;N_7 ZbxjP1`;sp>1v*f}kx^ HE*wl3%]C7xb56w>3&Lq5\t^{.?$ Ũmg7O}碫7V&u{K\V ~REDt]`P nA)Ǩ{DOq(΁A3/uÎFh{w̵4,:K>n΂H52I3JgԤmً\ߺc'I/i|Gh@Gh@[VkXG ӼpSԛZV p`l՞Āa%|p3ǽԜq3E&y[>+}vAT#a'H@F.&x Cc7gNoo)}PBBPstZ7ԅв/;nr3 #+_W +.ɩ~s|iVatk8Zx.B+W~yڃ~W\qW77|Lmo27lcZ~6msㆌDFSTHU ETh2^MHOɸes\$S,}s6} 14P"A-ѣ9mq9TuYc։tOVЅdW 7~W)%Ni܁1iYՕiiݦ㕳^"e\c֘*gN.&iCTw:\[Yhc{ tT95⣴$l,YSG  apABꦛ#foؐ"aF@Qɇ(J\'f@2bf>/&SʕK|ISMm&E_5v䀜%1iLvsz-{<@a V( BE߂|dq8]Kj` kH`9fMS`q3uc^fUƎ *Y@Qs!yŢ)gޗ XQ~1KUAqE`&u8L铟iV?qU(?rouQuݵ]%BgGa;ddbb("%{jJ3dbq@'ö7[rE!sZAC|9t#\VQPEPJÎf|Sq#3O1/(#L7אh(!ARz=L6۪֮0ۃqӮ}=RUC{uL9}?O~*`;X2a_K=j:yMV2g YeYxj[f+QN0 {SY}{d$OW?lˊX>7Zȝ*SVivtN&uGY^2-*hNGB2pXeʜNmRWNN/p`=q/iz)hNT7 ͡ݹ ! P?aڸ @r3)<+cQAf6E7q PjX]ohkEP=L_bҿ*F9_LB>|%ZD/Uq}hEl43r1{7(U̸p`yLHLD.Nv݌X֞ֆ۠fuW˒xFheV̨T0x䬙"n+:]hkp9=Pfp ! >bW|5{(*ᅇ䄲leN K@6: Y2efa`dHZoxUWeYnŞ$Tnm j) Y8Z'U%TazVz#.GF/]nÌFV)cRf>iohg95O0&gN1(K4LEIn C:luRWM\X.ns.poOvnPFxTx&^U^] ZV#I Y[1bR!"M[22g΁,-;P,0|ֻ`j?@%@`(Wr}>ءdP,,jƜ-QgQ'F䯀F4rcMf9u uZ͵;|d*%n^I47 ]WmKW b 1%5HfnN32?'f<݇Xƾ+0>33.gEx1N4A)A4)Q=)G1礅[YEĜa1~;ksJ*_T4a`%5VNYt ˖ 23͝t@&.0fB]7)9g{Od [tpc׵uqC>.?K#g*Ȅ-q @/M"vHZ]+'uR5?߸H;jϢʼnۧ1 2|/UX:$,GƫzAI5h"dL֡+(-uLe9MgkQ"[Q54#ɽT*8E[I E!64֒h{ռn8"sW90`/+5D6eºW>Qp#Aqŗ=pTy0m[9#[=X=֭@NL2N஼5P+ ew "V7wIhF*?>Ț}LDž:QR5>}QNg<~%N7JD{zF)6b@i1H 6 h_Z5_e*be'0aeR^iU{16^Uą}Qq&aс gtq1;sņvҩ&SpDV JѶܚx @?FbޣAqd-g|.': ="cbRѮe;8/ endstream endobj 273 0 obj << /Type /ObjStm /N 100 /First 917 /Length 4137 /Filter /FlateDecode >> stream x[[s9~:y'O*7g8oIMA;vd#IfR-vKTY4 [jUUWJy[IWJFVRAVF\xk]YVΨ=Tƺsя5GSPIe!!B`U%mmԕt*V YaOixGp;]%#4ztuK;`ZiӵtPhj0ӵӵAGBV9*u@'TN+DhYZB=+,fIW͞nXhDcfTڣch\`H=u xAhҁ$ց 3RŹJT+ Ry$tH[  JXEs=UXTQ=@`N pk̫  ZJ;/+О + Գ #!j^ dͫǰ ItƳYHpB4F3|*mFBi)X0P  J1.,vl9x,A<8&X>:ϯW_.'_xp:g h4dpz1?c[/AJ 80~ľ" 4h]c}f/ѿzǣo/&`2,T]J0 (VUn7ik#{oF#䦴sB%[52\dȅ{iZGՒ!bMr"#$X;{Pҡd1wՃ'.RAh4lؚJLOƓuRKkDvչޥM|rH4aބDԞbmP]z3+8K]ȀH:'j0# 5yVԼj/RMiB;QK6ɝM}GnY Dxܸ*Nd{6˰ Eg'W6󈤞-.mY9o4mZS;DUMxyO2ʱ&M N5PS $$Jnc$>刓,)#A[D)Wgy.94,"Hϡo Sk(A}њ G$[Zes|*Mn-dq8Tx]GmlVEK$I̲WRٗ[ئZYE2Wj9WdE8JQK/tp(]xn6'"d+떊{,[юMՒG6R' ɟtd~ ݤ@vӑf7Ӓ7`*RF(R8%rD)0\,T &3#2VJA"} >&Q`) n=;Z+},y4T<#.p#,FN֋-u0P+&R[J]_ORsES׷pr T>}Ay|K Dk)( mo ofXc*tt1Izb6j=K(HE@]֎Lʎr%sxȹ EЩM K[R#k*ىUؗF;VԦdҦZ>B-It2 *ڏwt5Nq9CmIЋ g_s")*k3'[ȳ_y|Z&*v텍iEwM=`Rep{н{q0G.? J{$OB)=x q(^őx%kV Gq*D#>M8_7b$~cq!.DL.q%hr&b&b~>m1:*aIZu&$t-#G1 OK 5N.. !ħlrD{v x|蛘4Iu ~~wp 6W/?tt '};n>SoXO k 6TSg{Χo+}Ol"O;6B_f8~Bjk[3wot/{׏//>6s*kKOz2o>rqjad wƚw}Ć~C\nq'pC81 0e4AWo^ՆSۨLG~JMew!u)==~`۔2}(/%KHޣ4jꍠRjj$PS:xۇ&P,v%`?*,kqeY2[S{sx9ׯ76E׭H);e 2n¦_5]7>ttr:XVxuBiCN%ػ9ף=Is&fDS=yz1t !r4;E>}S2\{(8j%ht:^_tT /x <[Sy !MlvS@op޽<ɴV 9dŃpWt__9Y2ع|!g=M_ͪ2^zdH?2)62T H9yxCJ%'Tv;6S,˹?kx;-ϵM(#5_nʣn^, Iz}e,ۏ^%vh2K'mef-~t49?f^ҫRX%z ]3Xn+aֱKVjd )U t\skVEލ-VQ g/zZc|Y k -mYB Z¦yjZ}Ɨ5po):qjߢ균Jkڵ-bbB@J] -!vk -v Ķحض-bbBl@lJM )!6k 6-z ĺجX-bbB@JU *!k V-j ĪXH{[ %j E\q٢^ endstream endobj 359 0 obj << /Author(Andreas Gruenbacher and Seth Arnold)/Title(AppArmor Technical Documentation)/Subject(AppArmor)/Creator(LaTeX with hyperref package)/CreationDate(20190617235538+0000)/ModDate(20190617235538+0000)/Producer(pdfTeX-1.40.18)/Keywords(AppArmor) /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017/Debian) kpathsea version 6.2.3) >> endobj 343 0 obj << /Type /ObjStm /N 18 /First 147 /Length 750 /Filter /FlateDecode >> stream xڅVj0}߯cP mSɃa^Nigd{m$̙I3L3$'"! HEXBP<_) 8(ezE|lz6 H] jq9! KT!1vAÉm*[Z@ Sى}DU@źՌ}Bn173z%%lSN'$'beDg?WrP% r6(5UdPRӌzY !Srozf'D"Dfu5 B Qщ|zhǰ:{(w^k@zz.)79lf}[APw(h]G}US|yiw>"ë"6^uގ~*7?@١_T6 endstream endobj 360 0 obj << /Type /XRef /Index [0 361] /Size 361 /W [1 3 1] /Root 358 0 R /Info 359 0 R /ID [ ] /Length 862 /Filter /FlateDecode >> stream x%9LQ& ,<}E\qeGe1Zؘ-ĜMl,-ZYP|{3s_f`c_TN"*©M,WD qm.Õi|\)nqEW۠-J:m p{A9 mĵh@5 wõVikAB[p=v?h.6 ]mCe6Ў;[E.Ѝ-^y(t N +t9QqEE~ uT:&1F׀08wz^"n<ĺ5DI>e3|'/>#\N|[[# N|5d8p"-ek\e}1P";RwUmƑjY\m\жg9v(Zx)@cPjcՠ@=hA#PY6Lޗ;Z,nQj61]Uf^09Ӣ>U]^mrUkыk,T]Հ7T Zj!pA\*2e&0݄(M LU80$ԃ%{0/ endstream endobj startxref 234384 %%EOF apparmor-2.13.3/parser/lib.h0000644000175000017500000000121313502024172013415 0ustar jjjj#ifndef __AA_LIB_H_ #define __AA_LIB_H_ #include #define autofree __attribute((cleanup(_aa_autofree))) #define autoclose __attribute((cleanup(_aa_autoclose))) #define autofclose __attribute((cleanup(_aa_autofclose))) #define asprintf _aa_asprintf int dirat_for_each(int dirfd, const char *name, void *data, int (* cb)(int, const char *, struct stat *, void *)); int isodigit(char c); long strntol(const char *str, const char **endptr, int base, long maxval, size_t n); int strn_escseq(const char **pos, const char *chrs, size_t n); int str_escseq(const char **pos, const char *chrs); #endif /* __AA_LIB_H_ */ apparmor-2.13.3/parser/parser_common.c0000644000175000017500000001034013502024172015507 0ustar jjjj/* * Copyright (c) 2010 - 2012 * Canonical Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical, * Ltd. */ #include #include #include "parser.h" /* Policy versioning is determined by a combination of 3 values: * policy_version: version of txt policy * parser_abi_version: version of abi revision of policy generated by parser * kernel_abi_version: version of abi revision for the kernel * * The version info is stored in a single 32 bit version field in the * header portion of each binary policy file. * * policy_version: * a gross revision number indicating what features and semantics are * expected by the text policy. This does not necessarily map directly * to a feature set as a kernel may not have all the supported features * patched/builtin. * * policy_version is not supported by kernels that only support v5 * kernel abi, so it will not be written when creating policy for * those kernels. * * kernel_abi_version: * should be set to the highest version supported by both the parser and * the kernel. * This allows new kernels to detect old userspaces, and new parsers * to support old kernels and policies semantics. * * parser_abi_version: * should be bumped when a compiler error or some other event happens * and policy cache needs to be forced to be recomputed, when the * policy_version or kernel version has not changed. * * parser_abi_version is not supported by kernels that only support * v5 kernel abi so it will not be written when creating policy for those * kernels. * * Default values set to v5 kernel abi before the different versioning * numbers where supported. */ uint32_t policy_version = 2; uint32_t parser_abi_version = 2; uint32_t kernel_abi_version = 5; int force_complain = 0; int perms_create = 0; /* perms contain create flag */ int net_af_max_override = -1; /* use kernel to determine af_max */ int kernel_load = 1; int kernel_supports_setload = 0; /* kernel supports atomic set loads */ int kernel_supports_network = 0; /* kernel supports network rules */ int kernel_supports_unix = 0; /* kernel supports unix socket rules */ int kernel_supports_policydb = 0; /* kernel supports new policydb */ int kernel_supports_mount = 0; /* kernel supports mount rules */ int kernel_supports_dbus = 0; /* kernel supports dbus rules */ int kernel_supports_diff_encode = 0; /* kernel supports diff_encode */ int kernel_supports_signal = 0; /* kernel supports signal rules */ int kernel_supports_ptrace = 0; /* kernel supports ptrace rules */ int kernel_supports_stacking = 0; /* kernel supports stacking */ int conf_verbose = 0; int conf_quiet = 0; int names_only = 0; int current_lineno = 1; int option = OPTION_ADD; dfaflags_t dfaflags = (dfaflags_t)(DFA_CONTROL_TREE_NORMAL | DFA_CONTROL_TREE_SIMPLE | DFA_CONTROL_MINIMIZE | DFA_CONTROL_DIFF_ENCODE); dfaflags_t warnflags = 0; const char *progname = __FILE__; char *profile_ns = NULL; char *profilename = NULL; char *current_filename = NULL; FILE *ofile = NULL; #ifdef FORCE_READ_IMPLIES_EXEC int read_implies_exec = 1; #else int read_implies_exec = 0; #endif void pwarn(const char *fmt, ...) { va_list arg; char *newfmt; if (conf_quiet || names_only || option == OPTION_REMOVE) return; if (asprintf(&newfmt, _("Warning from %s (%s%sline %d): %s"), profilename ? profilename : "stdin", current_filename ? current_filename : "", current_filename ? " " : "", current_lineno, fmt) == -1) return; va_start(arg, fmt); vfprintf(stderr, newfmt, arg); va_end(arg); free(newfmt); } apparmor-2.13.3/parser/signal.cc0000644000175000017500000001500513502024172014266 0ustar jjjj/* * Copyright (c) 2014 * Canonical, Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical * Ltd. */ #include #include #include #include #include #include #include #include #include "parser.h" #include "profile.h" #include "parser_yacc.h" #include "signal.h" #define MAXMAPPED_SIG 35 #define MINRT_SIG 128 /* base of RT sigs */ #define MAXRT_SIG 32 /* Max RT above MINRT_SIG */ /* Signal names mapped to and internal ordering */ static struct signal_map { const char *name; int num; } signal_map[] = { {"hup", 1}, {"int", 2}, {"quit", 3}, {"ill", 4}, {"trap", 5}, {"abrt", 6}, {"bus", 7}, {"fpe", 8}, {"kill", 9}, {"usr1", 10}, {"segv", 11}, {"usr2", 12}, {"pipe", 13}, {"alrm", 14}, {"term", 15}, {"stkflt", 16}, {"chld", 17}, {"cont", 18}, {"stop", 19}, {"stp", 20}, {"ttin", 21}, {"ttou", 22}, {"urg", 23}, {"xcpu", 24}, {"xfsz", 25}, {"vtalrm", 26}, {"prof", 27}, {"winch", 28}, {"io", 29}, {"pwr", 30}, {"sys", 31}, {"emt", 32}, {"exists", 35}, /* terminate */ {NULL, 0} }; /* this table is ordered post sig_map[sig] mapping */ static const char *const sig_names[MAXMAPPED_SIG + 1] = { "unknown", "hup", "int", "quit", "ill", "trap", "abrt", "bus", "fpe", "kill", "usr1", "segv", "usr2", "pipe", "alrm", "term", "stkflt", "chld", "cont", "stop", "stp", "ttin", "ttou", "urg", "xcpu", "xfsz", "vtalrm", "prof", "winch", "io", "pwr", "sys", "emt", "lost", "unused", "exists", /* always last existance test mapped to MAXMAPPED_SIG */ }; int parse_signal_mode(const char *str_mode, int *mode, int fail) { return parse_X_mode("signal", AA_VALID_SIGNAL_PERMS, str_mode, mode, fail); } static int find_signal_mapping(const char *sig) { if (strncmp("rtmin+", sig, 6) == 0) { char *end; unsigned long n = strtoul(sig + 6, &end, 10); if (end == sig || n > MAXRT_SIG) return -1; return MINRT_SIG + n; } else { for (int i = 0; signal_map[i].name; i++) { if (strcmp(sig, signal_map[i].name) == 0) return signal_map[i].num; } } return -1; } void signal_rule::extract_sigs(struct value_list **list) { struct value_list *entry, *tmp, *prev = NULL; list_for_each_safe(*list, entry, tmp) { int i = find_signal_mapping(entry->value); if (i != -1) { signals.insert(i); list_remove_at(*list, prev, entry); free_value_list(entry); } else { yyerror("unknown signal \"%s\"\n", entry->value); prev = entry; } } } void signal_rule::move_conditionals(struct cond_entry *conds) { struct cond_entry *cond_ent; list_for_each(conds, cond_ent) { /* for now disallow keyword 'in' (list) */ if (!cond_ent->eq) yyerror("keyword \"in\" is not allowed in signal rules\n"); if (strcmp(cond_ent->name, "set") == 0) { extract_sigs(&cond_ent->vals); } else if (strcmp(cond_ent->name, "peer") == 0) { move_conditional_value("signal", &peer_label, cond_ent); } else { yyerror("invalid signal rule conditional \"%s\"\n", cond_ent->name); } } } signal_rule::signal_rule(int mode_p, struct cond_entry *conds): signals(), peer_label(NULL), audit(0), deny(0) { if (mode_p) { mode = mode_p; if (mode & ~AA_VALID_SIGNAL_PERMS) yyerror("mode contains invalid permission for signals\n"); } else { mode = AA_VALID_SIGNAL_PERMS; } move_conditionals(conds); free_cond_list(conds); } ostream &signal_rule::dump(ostream &os) { if (audit) os << "audit "; if (deny) os << "deny "; os << "signal"; if (mode != AA_VALID_SIGNAL_PERMS) { os << " ("; if (mode & AA_MAY_SEND) os << "send "; if (mode & AA_MAY_RECEIVE) os << "receive "; os << ")"; } if (!signals.empty()) { os << " set=("; for (Signals::iterator i = signals.begin(); i != signals.end(); i++) { if (i != signals.begin()) os << ", "; if (*i < MINRT_SIG) os << sig_names[*i]; else os << "rtmin+" << (*i - MINRT_SIG); } os << ")"; } if (peer_label) os << " " << peer_label; os << ",\n"; return os; } int signal_rule::expand_variables(void) { return expand_entry_variables(&peer_label); } /* do we want to warn once/profile or just once per compile?? */ static void warn_once(const char *name) { static const char *warned_name = NULL; if ((warnflags & WARN_RULE_NOT_ENFORCED) && warned_name != name) { cerr << "Warning from profile " << name << " ("; if (current_filename) cerr << current_filename; else cerr << "stdin"; cerr << ") signal rules not enforced\n"; warned_name = name; } } int signal_rule::gen_policy_re(Profile &prof) { std::ostringstream buffer; std::string buf; pattern_t ptype; int pos; /* Currently do not generate the rules if the kernel doesn't support * it. We may want to switch this so that a compile could be * used for full support on kernels that don't support the feature */ if (!kernel_supports_signal) { warn_once(prof.name); return RULE_NOT_SUPPORTED; } if (signals.size() == 0) { /* not conditional on signal set, so will generate a label * rule as well */ buffer << "(" << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_LABEL << "\\x" << AA_CLASS_SIGNAL << "|"; } buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_SIGNAL; if (signals.size()) { buffer << "["; for (Signals::iterator i = signals.begin(); i != signals.end(); i++) { buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << *i; } buffer << "]"; } else { /* match any char */ buffer << "."; } if (signals.size() == 0) { /* close alternation */ buffer << ")"; } if (peer_label) { ptype = convert_aaregex_to_pcre(peer_label, 0, glob_default, buf, &pos); if (ptype == ePatternInvalid) goto fail; buffer << buf; } else { buffer << anyone_match_pattern; } buf = buffer.str(); if (mode & (AA_MAY_SEND | AA_MAY_RECEIVE)) { if (!prof.policy.rules->add_rule(buf.c_str(), deny, mode, audit, dfaflags)) goto fail; } return RULE_OK; fail: return RULE_ERROR; } apparmor-2.13.3/parser/aa-teardown.pod0000644000175000017500000000214113502024172015405 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (c) 2018 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Novell, Inc. # ---------------------------------------------------------------------- =pod =head1 NAME aa-teardown - unload all AppArmor profiles =head1 SYNOPSIS B =head1 DESCRIPTION aa-teardown unloads all AppArmor profiles =head1 BUGS If you find any bugs, please report them at L. =head1 SEE ALSO apparmor(7), apparmor.d(5), and L. =cut apparmor-2.13.3/parser/signal.h0000644000175000017500000000301313502024172014124 0ustar jjjj/* * Copyright (c) 2014 * Canonical, Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical * Ltd. */ #ifndef __AA_SIGNAL_H #define __AA_SIGNAL_H #include "parser.h" #include "rule.h" #include "profile.h" #define AA_MAY_SEND (1 << 1) #define AA_MAY_RECEIVE (1 << 2) #define AA_VALID_SIGNAL_PERMS (AA_MAY_SEND | AA_MAY_RECEIVE) typedef set Signals; int parse_signal_mode(const char *str_mode, int *mode, int fail); class signal_rule: public rule_t { void extract_sigs(struct value_list **list); void move_conditionals(struct cond_entry *conds); public: Signals signals; char *peer_label; int mode; int audit; int deny; signal_rule(int mode, struct cond_entry *conds); virtual ~signal_rule() { signals.clear(); free(peer_label); }; virtual ostream &dump(ostream &os); virtual int expand_variables(void); virtual int gen_policy_re(Profile &prof); virtual void post_process(Profile &prof unused) { }; }; #endif /* __AA_SIGNAL_H */ apparmor-2.13.3/parser/parser_symtab.c0000644000175000017500000004617013502024172015530 0ustar jjjj/* * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 * NOVELL (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. */ #include #include #include #include #include #include #include "immunix.h" #include "parser.h" typedef int (*comparison_fn_t)(const void *, const void *); typedef void (*__free_fn_t)(void *); enum var_type { sd_boolean, sd_set, }; struct symtab { char *var_name; enum var_type type; int boolean; struct set_value *values; struct set_value *expanded; }; static void *my_symtab = NULL; static int __expand_variable(struct symtab *symbol); static struct symtab *new_symtab_entry(const char *name) { struct symtab *n = (struct symtab *) calloc(1, sizeof(*n)); if (!n) { PERROR("Failed to allocate memory: %s\n", strerror(errno)); return NULL; } n->var_name = strndup(name, PATH_MAX); if (!n->var_name) { PERROR("Failed to allocate memory: %s\n", strerror(errno)); free(n); return NULL; } return n; } static struct set_value *new_set_value(const char *val) { struct set_value *n = (struct set_value *) calloc(1, sizeof(*n)); if (!n) { PERROR("Failed to allocate memory: %s\n", strerror(errno)); return NULL; } n->val = strndup(val, PATH_MAX); if (!n->val) { PERROR("Failed to allocate memory: %s\n", strerror(errno)); free(n); return NULL; } return n; } static void free_values(struct set_value *val) { struct set_value *i = val, *tmp; while (i) { if (i->val) free(i->val); tmp = i; i = i->next; free(tmp); } } static void free_symtab(struct symtab *symtab) { if (!symtab) return; if (symtab->var_name) free(symtab->var_name); free_values(symtab->values); free_values(symtab->expanded); free(symtab); } /* abstract this out in case we switch data structures */ static void add_to_set(struct set_value **list, const char *val) { struct set_value *new_item = new_set_value(val); new_item->next = *list; *list = new_item; } static int compare_symtabs(const void *a, const void *b) { char *a_name = ((struct symtab *) a)->var_name; char *b_name = ((struct symtab *) b)->var_name; return strcmp(a_name, b_name); } static struct symtab *lookup_existing_symbol(const char *var) { struct symtab *tmp, **lookup; struct symtab *result = NULL; tmp = new_symtab_entry(var); if (!tmp) { goto out; } lookup = (struct symtab **) tfind(tmp, &my_symtab, (comparison_fn_t) &compare_symtabs); if (!lookup) { goto out; } result = (*lookup); out: free_symtab(tmp); return result; } /* add_boolean_var * creates copies of arguments, so caller can free them after use */ int add_boolean_var(const char *var, int value) { struct symtab *n, **result; int rc = 0; n = new_symtab_entry(var); if (!n) { rc = ENOMEM; goto err; } n->type = sd_boolean; n->boolean = value; result = (struct symtab **) tsearch(n, &my_symtab, (comparison_fn_t) &compare_symtabs); if (!result) { PERROR("Failed to allocate memory: %s\n", strerror(errno)); rc = errno; goto err; } if (*result != n) { /* already existing variable */ PERROR("'%s' is already defined\n", var); rc = 1; goto err; } return 0; err: free_symtab(n); return rc; }; int get_boolean_var(const char *var) { struct symtab *result; int rc = 0; result = lookup_existing_symbol(var); if (!result) { rc = -1; goto out; } if (result->type != sd_boolean) { PERROR("Variable %s is not a boolean variable\n", var); rc = -2; /* XXX - might change this to specific values */ goto out; } rc = result->boolean; out: return rc; } /* new_set_var * creates copies of arguments, so caller can free them after use */ int new_set_var(const char *var, const char *value) { struct symtab *n, **result; int rc = 0; n = new_symtab_entry(var); if (!n) { rc = ENOMEM; goto err; } n->type = sd_set; add_to_set(&(n->values), value); result = (struct symtab **) tsearch(n, &my_symtab, (comparison_fn_t) &compare_symtabs); if (!result) { PERROR("Failed to allocate memory: %s\n", strerror(errno)); rc = errno; goto err; } if (*result != n) { /* already existing variable */ PERROR("'%s' is already defined\n", var); rc = 1; goto err; } return 0; err: free_symtab(n); return rc; } /* add_set_value * creates copies of arguments, so caller can free them after use */ int add_set_value(const char *var, const char *value) { struct symtab *result; int rc = 0; result = lookup_existing_symbol(var); if (!result) { PERROR("Failed to find declaration for: %s\n", var); rc = 1; goto out; } if (result->type != sd_set) { PERROR("Variable %s is not a set variable\n", var); rc = 2; /* XXX - might change this to specific values */ goto out; } if (strcmp(result->var_name, var) != 0) { PERROR("ASSERT: tfind found %s when looking up variable %s\n", result->var_name, var); exit(1); } add_to_set(&(result->values), value); out: return rc; } /* returns a pointer to the value list, which should be used as the * argument to the get_next_set_value() function. */ struct set_value *get_set_var(const char *var) { struct symtab *result; struct set_value *valuelist = NULL; result = lookup_existing_symbol(var); if (!result) { goto out; } if (result->type != sd_set) { goto out; } if (strcmp(result->var_name, var) != 0) { PERROR("ASSERT: tfind found %s when looking up variable %s\n", result->var_name, var); exit(1); } if (!result->expanded) { int err = __expand_variable(result); if (err) { PERROR("failure expanding variable %s\n", var); exit(1); } } valuelist = result->expanded; out: return valuelist; } /* iterator to walk the list of set values */ char *get_next_set_value(struct set_value **list) { struct set_value *next; char *ret; if (!list || !(*list)) return NULL; ret = (*list)->val; next = (*list)->next; (*list) = next; return ret; } /* delete_symbol * removes an individual variable from the symbol table. We don't * support this in the language, but for special variables that change * between profiles, we need this. */ int delete_set_var(const char *var_name) { int rc = 0; struct symtab **result, *n, *var; n = new_symtab_entry(var_name); if (!n) { rc = ENOMEM; goto out; } result = (struct symtab **) tfind(n, &my_symtab, (comparison_fn_t) &compare_symtabs); if (!result) { /* XXX Warning? */ goto out; } var = (*result); result = (struct symtab **) tdelete(n, &my_symtab, (comparison_fn_t) &compare_symtabs); if (!result) { PERROR("ASSERT: delete_set_var: tfind found var %s but tdelete failed to delete it\n", var_name); exit(1); } if (var->type != sd_set) { PERROR("ASSERT: delete_set_var: deleting %s but is a boolean variable\n", var_name); exit(1); } free_symtab(var); out: free_symtab(n); return rc; } static void *seenlist = NULL; static int is_seen(const char *var) { char **lookup; lookup = (char **) tfind(var, &seenlist, (comparison_fn_t) &strcmp); return (lookup != NULL); } static void push_seen_var(const char *var) { char **lookup; lookup = (char **) tsearch(var, &seenlist, (comparison_fn_t) &strcmp); if (*lookup != var) { PERROR("ASSERT: '%s' is already in the seenlist\n", var); exit(1); } } static void pop_seen_var(const char *var) { char **lookup; lookup = (char **) tdelete(var, &seenlist, (comparison_fn_t) &strcmp); if (lookup == NULL) { PERROR("ASSERT: popped var '%s' not found on the seenlist\n", var); exit(1); } } static int __expand_variable(struct symtab *symbol) { struct set_value *list, *expanded = NULL; int retval = 0; struct var_string *split = NULL; if (symbol->type == sd_boolean) { PERROR("Referenced variable %s is a boolean used in set context\n", symbol->var_name); return 2; } /* already done */ if (symbol->expanded) return 0; push_seen_var(symbol->var_name); for (list = symbol->values; list; list = list->next) { struct set_value *work_list = new_set_value(list->val); while (work_list) { struct symtab *ref; struct set_value *ref_item; struct set_value *t_value = work_list; int rc; work_list = work_list->next; split = split_out_var(t_value->val); if (!split) { /* fully expanded */ add_to_set(&expanded, t_value->val); goto next; } if (is_seen(split->var)) { PERROR("Variable @{%s} is referenced recursively (by @{%s})\n", split->var, symbol->var_name); retval = 1; free_values(t_value); goto out; } ref = lookup_existing_symbol(split->var); if (!ref) { PERROR("Variable @{%s} references undefined variable @{%s}\n", symbol->var_name, split->var); retval = 3; free_values(t_value); goto out; } rc = __expand_variable(ref); if (rc != 0) { retval = rc; free_values(t_value); goto out; } if (!ref->expanded) { PERROR("ASSERT: Variable @{%s} should have been expanded but isn't\n", split->var); exit(1); } for (ref_item = ref->expanded; ref_item; ref_item = ref_item->next) { char *expanded_string; if (!asprintf(&expanded_string, "%s%s%s", split->prefix ? split->prefix : "", ref_item->val, split->suffix ? split->suffix : "")) { PERROR("Out of memory\n"); exit(1); } add_to_set(&work_list, expanded_string); free(expanded_string); } next: t_value->next = NULL; free_values(t_value); free_var_string(split); } } symbol->expanded = expanded; out: pop_seen_var(symbol->var_name); free_var_string(split); return retval; } static void expand_variable(const void *nodep, VISIT value, int level unused) { struct symtab **t = (struct symtab **) nodep; if (value == preorder || value == endorder) return; if ((*t)->type == sd_boolean) return; __expand_variable(*t); } void expand_variables(void) { twalk(my_symtab, &expand_variable); } static inline void dump_set_values(struct set_value *value) { struct set_value *t = value; while (t) { printf(" \"%s\"", t->val); t = t->next; } } static void __dump_symtab_entry(struct symtab *entry, int do_expanded) { switch (entry->type) { case sd_boolean: printf("$%s = %s\n", entry->var_name, entry->boolean ? "true" : "false"); break; case sd_set: printf("@%s =", entry->var_name); if (do_expanded) { if (!entry->expanded) { __expand_variable(entry); } dump_set_values(entry->expanded); } else { dump_set_values(entry->values); } printf("\n"); break; default: PERROR("ASSERT: unknown symbol table type for %s\n", entry->var_name); exit(1); } } static void dump_symtab_entry(const void *nodep, VISIT value, int level unused) { struct symtab **t = (struct symtab **) nodep; if (value == preorder || value == endorder) return; __dump_symtab_entry(*t, 0); } static void dump_expanded_symtab_entry(const void *nodep, VISIT value, int level unused) { struct symtab **t = (struct symtab **) nodep; if (value == preorder || value == endorder) return; __dump_symtab_entry(*t, 1); } void dump_symtab(void) { twalk(my_symtab, &dump_symtab_entry); } void dump_expanded_symtab(void) { twalk(my_symtab, &dump_expanded_symtab_entry); } void free_symtabs(void) { if (my_symtab) tdestroy(my_symtab, (__free_fn_t)&free_symtab); my_symtab = NULL; } #ifdef UNIT_TEST #include "unit_test.h" int test_compare_symtab(void) { int rc = 0; int retval; struct symtab *a, *b, *c; a = new_symtab_entry("blah"); b = new_symtab_entry("suck"); MY_TEST(a && b, "allocation test"); retval = compare_symtabs(a, b); MY_TEST(retval < 0, "comparison 1"); retval = compare_symtabs(b, a); MY_TEST(retval > 0, "comparison 2"); retval = compare_symtabs(b, a); MY_TEST(retval != 0, "comparison 3"); retval = compare_symtabs(b, b); MY_TEST(retval == 0, "comparison 4"); c = new_symtab_entry("blah"); retval = compare_symtabs(a, c); MY_TEST(retval == 0, "comparison 5"); free_symtab(a); free_symtab(b); free_symtab(c); return rc; } int test_seenlist(void) { int rc = 0; MY_TEST(!is_seen("oogabooga"), "lookup unseen variable"); push_seen_var("oogabooga"); MY_TEST(is_seen("oogabooga"), "lookup seen variable 1"); MY_TEST(!is_seen("not_seen"), "lookup unseen variable 2"); push_seen_var("heebiejeebie"); MY_TEST(is_seen("oogabooga"), "lookup seen variable 2"); MY_TEST(is_seen("heebiejeebie"), "lookup seen variable 3"); MY_TEST(!is_seen("not_seen"), "lookup unseen variable 3"); pop_seen_var("oogabooga"); MY_TEST(!is_seen("oogabooga"), "lookup unseen variable 4"); MY_TEST(is_seen("heebiejeebie"), "lookup seen variable 4"); MY_TEST(!is_seen("not_seen"), "lookup unseen variable 5"); pop_seen_var("heebiejeebie"); MY_TEST(!is_seen("heebiejeebie"), "lookup unseen variable 6"); //pop_seen_var("not_seen"); /* triggers assert */ return rc; } int test_add_set_to_boolean(void) { int rc = 0; int retval; /* test adding a set value to a boolean variable */ retval = add_boolean_var("not_a_set_variable", 1); MY_TEST(retval == 0, "new boolean variable 3"); retval = add_set_value("not_a_set_variable", "a set value"); MY_TEST(retval != 0, "add set value to boolean"); free_symtabs(); return rc; } int test_expand_bool_within_set(void) { int rc = 0; int retval; struct symtab *retsym; /* test expanding a boolean var within a set variable */ retval = add_boolean_var("not_a_set_variable", 1); MY_TEST(retval == 0, "new boolean variable 4"); retval = new_set_var("set_variable", "set_value@{not_a_set_variable}"); MY_TEST(retval == 0, "add set value with embedded boolean"); retsym = lookup_existing_symbol("set_variable"); MY_TEST(retsym != NULL, "get set variable w/boolean"); retval = __expand_variable(retsym); MY_TEST(retval != 0, "expand set variable with embedded boolean"); free_symtabs(); return rc; } int test_expand_recursive_set_vars(void) { int rc = 0; int retval; struct symtab *retsym; /* test expanding a recursive var within a set variable */ retval = new_set_var("recursive_1", "set_value@{recursive_2}"); MY_TEST(retval == 0, "new recursive set variable 1"); retval = new_set_var("recursive_2", "set_value@{recursive_3}"); MY_TEST(retval == 0, "new recursive set variable 2"); retval = new_set_var("recursive_3", "set_value@{recursive_1}"); MY_TEST(retval == 0, "new recursive set variable 3"); retsym = lookup_existing_symbol("recursive_1"); MY_TEST(retsym != NULL, "get recursive set variable"); retval = __expand_variable(retsym); MY_TEST(retval != 0, "expand recursive set variable"); free_symtabs(); return rc; } int test_expand_undefined_set_var(void) { int rc = 0; int retval; struct symtab *retsym; /* test expanding an undefined var within a set variable */ retval = new_set_var("defined_var", "set_value@{undefined_var}"); MY_TEST(retval == 0, "new undefined test set variable"); retsym = lookup_existing_symbol("defined_var"); MY_TEST(retsym != NULL, "get undefined test set variable"); retval = __expand_variable(retsym); MY_TEST(retval != 0, "expand undefined set variable"); free_symtabs(); return rc; } int test_expand_set_var_during_dump(void) { int rc = 0; int retval; struct symtab *retsym; /* test expanding an defined var within a set variable during var dump*/ retval = new_set_var("set_var_1", "set_value@{set_var_2}"); MY_TEST(retval == 0, "new dump expansion set variable 1"); retval = new_set_var("set_var_2", "some other set_value"); MY_TEST(retval == 0, "new dump expansion set variable 2"); retsym = lookup_existing_symbol("set_var_1"); MY_TEST(retsym != NULL, "get dump expansion set variable 1"); __dump_symtab_entry(retsym, 0); __dump_symtab_entry(retsym, 1); __dump_symtab_entry(retsym, 0); free_symtabs(); return rc; } int test_delete_set_var(void) { int rc = 0; int retval; retval = new_set_var("deleteme", "delete this variable"); MY_TEST(retval == 0, "new delete set variable"); retval = delete_set_var("deleteme"); MY_TEST(retval == 0, "delete set variable"); free_symtabs(); return rc; } int main(void) { int rc = 0; int retval; struct set_value *retptr; rc = test_compare_symtab(); retval = test_seenlist(); if (rc == 0) rc = retval; retval = test_add_set_to_boolean(); if (rc == 0) rc = retval; retval = test_expand_bool_within_set(); if (rc == 0) rc = retval; retval = test_expand_recursive_set_vars(); if (rc == 0) rc = retval; retval = test_expand_undefined_set_var(); if (rc == 0) rc = retval; retval = test_expand_set_var_during_dump(); if (rc == 0) rc = retval; retval = test_delete_set_var(); if (rc == 0) rc = retval; retval = new_set_var("test", "test value"); MY_TEST(retval == 0, "new set variable 1"); retval = new_set_var("test", "different value"); MY_TEST(retval != 0, "new set variable 2"); retval = new_set_var("testing", "testing"); MY_TEST(retval == 0, "new set variable 3"); retval = new_set_var("monopuff", "Mockingbird"); MY_TEST(retval == 0, "new set variable 4"); retval = new_set_var("stereopuff", "Unsupervised"); MY_TEST(retval == 0, "new set variable 5"); retval = add_set_value("stereopuff", "Fun to Steal"); MY_TEST(retval == 0, "add set value 1"); retval = add_set_value("stereopuff", "/in/direction"); MY_TEST(retval == 0, "add set value 2"); retval = add_set_value("no_such_variable", "stereopuff"); MY_TEST(retval != 0, "add to non-existent set var"); retval = add_boolean_var("abuse", 0); MY_TEST(retval == 0, "new boolean variable 1"); retval = add_boolean_var("abuse", 1); MY_TEST(retval != 0, "duplicate boolean variable 1"); retval = add_boolean_var("stereopuff", 1); MY_TEST(retval != 0, "duplicate boolean variable 2"); retval = add_boolean_var("shenanigan", 1); MY_TEST(retval == 0, "new boolean variable 2"); retval = get_boolean_var("shenanigan"); MY_TEST(retval == 1, "get boolean variable 1"); retval = get_boolean_var("abuse"); MY_TEST(retval == 0, "get boolean variable 2"); retval = get_boolean_var("non_existant"); MY_TEST(retval < 0, "get nonexistant boolean variable"); retval = get_boolean_var("stereopuff"); MY_TEST(retval < 0, "get boolean variable that's declared a set var"); retptr = get_set_var("daves_not_here_man"); MY_TEST(retptr == NULL, "get non-existent set variable"); retptr = get_set_var("abuse"); MY_TEST(retptr == NULL, "get set variable that's declared a boolean"); /* test walking set values */ retptr = get_set_var("monopuff"); MY_TEST(retptr != NULL, "get set variable 1"); retval = strcmp(get_next_set_value(&retptr), "Mockingbird"); MY_TEST(retval == 0, "get set value 1"); MY_TEST(get_next_set_value(&retptr) == NULL, "get no more set values 1"); retval = new_set_var("eek", "Mocking@{monopuff}bir@{stereopuff}d@{stereopuff}"); MY_TEST(retval == 0, "new set variable 4"); dump_symtab(); expand_variables(); dump_symtab(); dump_expanded_symtab(); free_symtabs(); return rc; } #endif /* UNIT_TEST */ apparmor-2.13.3/parser/apparmor_parser.8.html0000644000175000017500000003675113502024374016752 0ustar jjjj
 

NAME

apparmor_parser - loads AppArmor profiles into the kernel

SYNOPSIS

apparmor_parser [options] <command> [profiles]...

apparmor_parser [options] <command>

apparmor_parser [-hv] [--help] [--version]

DESCRIPTION

apparmor_parser is used as a general tool to compile, and manage AppArmor policy, including loading new apparmor.d(5) profiles into the Linux kernel.

AppArmor profiles restrict the operations available to processes.

The profiles are loaded into the Linux kernel by the apparmor_parser program. The profiles may be specified by file name or a directory name containing a set of profiles. If a directory is specified then the apparmor_parser will try to do a profile load for each file in the directory that is not a dot file, or explicitly black listed (*.dpkg-new, *.dpkg-old, *.dpkg-dist, *.dpkg-bak, *.dpkg-remove, *.pacsave, *.pacnew, *.rpmnew, *.rpmsave, *.orig, *.rej, *~). The apparmor_parser will fall back to taking input from standard input if a profile or directory is not supplied.

The input supplied to apparmor_parser should be in the format described in apparmor.d(5).

COMMANDS

The command set is broken into four subcategories.

unprivileged commands

Commands that don't require any privilege and don't operate on profiles.

unprivileged profile commands

Commands that operate on a profile either specified on the command line or read from stdin if no profile was specified.

privileged commands

Commands that require the MAC_ADMIN capability within the affected AppArmor namespace to load policy into the kernel or filesystem write permissions to update the affected privileged files (cache etc).

privileged profile commands

Commands that require privilege and operate on profiles.

Unprivileged commands

-V, --version

Print the version number and exit.

-h, --help

Give a quick reference guide.

Unprivileged profile commands

-N, --names

Produce a list of policies from a given set of profiles (implies -K).

-p, --preprocess

Apply preprocessing to the input profile(s) by flattening includes into the output profile and dump to stdout.

-S, --stdout

Writes a binary (cached) profile to stdout (implies -K and -T).

-o file, --ofile file

Writes a binary (cached) profile to the specified file (implies -K and -T)

Privileged commands

--purge-cache

Unconditionally clear out cached profiles.

Privileged profile commands

-a, --add

Insert the AppArmor definitions given into the kernel. This is the default action. This gives an error message if a AppArmor definition by the same name already exists in the kernel, or if the parser doesn't understand its input. It reports when an addition succeeded.

-r, --replace

This flag is required if an AppArmor definition by the same name already exists in the kernel; used to replace the definition already in the kernel with the definition given on standard input.

-R, --remove

This flag is used to remove an AppArmor definition already in the kernel. Note that it still requires a complete AppArmor definition as described in apparmor.d(5) even though the contents of the definition aren't used.

OPTIONS

-B, --binary

Treat the profile files specified on the command line (or stdin if none specified) as binary cache files, produced with the -S or -o options, and load to the kernel as specified by -a, -r, and -R (implies -K and -T).

-C, --Complain

Force the profile to load in complain mode.

-b n, --base n

Set the base directory for resolving #include directives defined as relative paths.

-I n, --Include n

Add element n to the search path when resolving #include directives defined as an absolute paths.

-f n, --subdomainfs n

Set the location of the apparmor security filesystem (default is "/sys/kernel/security/apparmor").

-M n, --features-file n

Use the features file located at path "n" (default is /etc/apparmor.d/cache/.features). If the --cache-loc option is present, the ".features" file in the specified cache directory is used.

-m n, --match-string n

Only use match features "n".

-n n, --namespace-string n

Force a profile to load in the namespace "n".

-X, --readimpliesX

In the case of profiles that are loading on systems were READ_IMPLIES_EXEC is set in the kernel for a given process, load the profile so that any "r" flags are processed as "mr".

-k, --show-cache

Report the cache processing (hit/miss details) when loading or saving cached profiles.

-K, --skip-cache

Perform no caching at all: disables -W, implies -T.

-T, --skip-read-cache

By default, if a profile's cache is found in the location specified by --cache-loc and the timestamp is newer than the profile, it will be loaded from the cache. This option disables this cache loading behavior.

-W, --write-cache

Write out cached profiles to the location specified in --cache-loc. Off by default. In cases where abstractions have been changed, and the parser is running with "--replace", it may make sense to also use "--skip-read-cache" with the "--write-cache" option.

--skip-bad-cache

Skip updating the cache if it contains cached profiles in a bad or inconsistent state

-L, --cache-loc

Set the location(s) of the cache directory. This option can accept a comma separated list of directories, which will be searched in order to find a matching cache. The first matching cache file found is used even if a directory later in the search order may contain a newer cache file.

If multiple directories are specified and --write-cache has been specified then cache writes will be made to the first directory in the list, all other directories will be treated as read only.

If a cache directory name needs to have a comma as part of the name, it can be specified by using a backslash to escape the comma character in the directory name.

If not specified the cache location defaults to /var/cache/apparmor

Print the cache directory location. This path will be a subdirectory of the directory specified by --cache-loc. The subdirectory used will be influenced by the features available in the currently running kernel or by the features specified with the --match-string or --features-file options.

-Q, --skip-kernel-load

Perform all actions except the actual loading of a profile into the kernel. This is useful for testing profile generation, caching, etc, without making changes to the running kernel profiles.

This also removes the need for privilege to execute the commands that manage policy in the kernel

-q, --quiet

Do not report on the profiles as they are loaded, and not show warnings.

-v, --verbose

Report on the profiles as they are loaded, and show warnings.

--warn=n

Enable various warnings during policy compilation. A single dump flag can be specified per --warn option, but the --warn flag can be passed multiple times.

  apparmor_parser --warn=rules-not-enforced ...

Use --help=warn to see a full list of which warn flags are supported.

-d, --debug

Given once, only checks the profiles to ensure syntactic correctness. Given twice, dumps its interpretation of the profile for checking.

-D n, --dump=n

Debug flag for dumping various structures and passes of policy compilation. A single dump flag can be specified per --dump option, but the dump flag can be passed multiple times. Note progress flags tend to also imply the matching stats flag.

  apparmor_parser --dump=dfa-stats --dump=trans-stats <file>

Use --help=dump to see a full list of which dump flags are supported

-j n, --jobs=n

Set the number of jobs used to compile the specified policy. Where n can be

  #    - a specific number of jobs
  auto - the # of cpus in the in the system
  x#   - # * number of cpus

Eg. -j8 OR --jobs=8 allows for 8 parallel jobs -jauto OR --jobs=auto sets the jobs to the # of cpus -jx4 OR --jobs=x4 sets the jobs to # of cpus * 4 -jx1 is equivalent to -jauto

The default value is the number of cpus in the system.

--max-jobs n

Set a hard cap on the value that can be specified by the --jobs flag. It takes the same set of options available to the --jobs option, and defaults to 8*cpus

-O n, --optimize=n

Set the optimization flags used by policy compilation. A single optimization flag can be toggled per -O option, but the optimize flag can be passed multiple times. Turning off some phases of the optimization can make it so that policy can't complete compilation due to size constraints (it is entirely possible to create a dfa with millions of states that will take days or longer to compile).

Note: The parser is set to use a balanced default set of flags, that will result in reasonable compression but not take excessive amounts of time to complete.

Use --help=optimize to see a full list of which optimization flags are supported.

--abort-on-error Abort processing of profiles on the first error encountered, otherwise the parser will continue to try to compile other profiles if specified.

Note: If an error is encountered while processing profiles the last error encountered will be used to set the exit code.

--skip-bad-cache-rebuild The default behavior of the parser is to check if a cached version of a profile exists and if it does it attempt to load it into the kernel. If that load is rejected, then the parser will attempt to rebuild the cache file, and load again.

This option tells the parser to not attempt to rebuild the cache on failure, instead the parser continues on with processing the remaining profiles.

--config-file

Specify the config file to use instead of /etc/apparmor/parser.conf. This option will be processed early before regular options regardless of the order it is specified in.

Print the config file location that will be used.

CONFIG FILE

An optional config file /etc/apparmor/parser.conf can be used to specify the default options for the parser, which then can be overridden using the command line options.

The config file ignores leading whitespace and treats lines that begin with # as comments. Config options are specified one per line using the same format as the longform command line options (without the preceding --).

Eg. #comment

    optimize=no-expr-tree
    optimize=compress-fast

As with the command line some options accumulate and others override, ie. when there are conflicting versions of switch the last option is the one chosen.

Eg. Optimize=no-minimize Optimize=minimize

would result in Optimize=minimize being set.

The Include, Dump, and Optimize options accululate except for the inversion option (no-X vs. X), and a couple options that work by setting/clearing multiple options (compress-small). In that case the option will override the flags it sets but will may accumulate with others.

All other options override previously set values.

BUGS

If you find any bugs, please report them at https://bugs.launchpad.net/apparmor/+filebug.

SEE ALSO

apparmor(7), apparmor.d(5), subdomain.conf(5), aa_change_hat(2), and https://wiki.apparmor.net.

 
apparmor-2.13.3/parser/libapparmor_re/0000755000175000017500000000000013502024172015477 5ustar jjjjapparmor-2.13.3/parser/libapparmor_re/flex-tables.h0000644000175000017500000000143013502024172020054 0ustar jjjj#ifndef __FLEX_TABLES_H #define __FLEX_TABLES_H #include #include #define YYTH_MAGIC 0xF13C57B1 #define YYTH_FLAG_DIFF_ENCODE 1 struct table_set_header { uint32_t th_magic; /* TH_MAGIC */ uint32_t th_hsize; uint32_t th_ssize; uint16_t th_flags; /* char th_version[]; char th_name[]; char th_pad64[];*/ } __attribute__ ((packed)); #define YYTD_ID_ACCEPT 1 #define YYTD_ID_BASE 2 #define YYTD_ID_CHK 3 #define YYTD_ID_DEF 4 #define YYTD_ID_EC 5 #define YYTD_ID_META 6 #define YYTD_ID_ACCEPT2 7 #define YYTD_ID_NXT 8 #define YYTD_DATA8 1 #define YYTD_DATA16 2 #define YYTD_DATA32 4 struct table_header { uint16_t td_id; uint16_t td_flags; uint32_t td_hilen; uint32_t td_lolen; /* char td_data[]; char td_pad64[];*/ } __attribute__ ((packed)); #endif apparmor-2.13.3/parser/libapparmor_re/expr-tree.cc0000644000175000017500000003764413502024172017737 0ustar jjjj/* * (C) 2006, 2007 Andreas Gruenbacher * Copyright (c) 2003-2008 Novell, Inc. (All rights reserved) * Copyright 2009-2013 Canonical Ltd. * * The libapparmor library is licensed under the terms of the GNU * Lesser General Public License, version 2.1. Please see the file * COPYING.LGPL. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * * Functions to create/manipulate an expression tree for regular expressions * that have been parsed. * * The expression tree can be used directly after the parse creates it, or * it can be factored so that the set of important nodes is smaller. * Having a reduced set of important nodes generally results in a dfa that * is closer to minimum (fewer redundant states are created). It also * results in fewer important nodes in a the state set during subset * construction resulting in less memory used to create a dfa. * * Generally it is worth doing expression tree simplification before dfa * construction, if the regular expression tree contains any alternations. * Even if the regular expression doesn't simplification should be fast * enough that it can be used with minimal overhead. */ #include #include #include "expr-tree.h" #include "apparmor_re.h" /* Use a single static EpsNode as it carries no node specific information */ EpsNode epsnode; ostream &operator<<(ostream &os, uchar c) { const char *search = "\a\033\f\n\r\t|*+[](). ", *replace = "aefnrt|*+[](). ", *s; if ((s = strchr(search, c)) && *s != '\0') { os << '\\' << replace[s - search]; } else if (c < 32 || c >= 127) { os << '\\' << '0' << char ('0' + (c >> 6)) << char ('0' + ((c >> 3) & 7)) << char ('0' + (c & 7)); } else { os << (char)c; } return os; } /** * Text-dump a state (for debugging). */ ostream &operator<<(ostream &os, const NodeSet &state) { os << '{'; if (!state.empty()) { NodeSet::iterator i = state.begin(); for (;;) { os << (*i)->label; if (++i == state.end()) break; os << ','; } } os << '}'; return os; } ostream &operator<<(ostream &os, Node &node) { node.dump(os); return os; } /** * hash_NodeSet - generate a hash for the Nodes in the set */ unsigned long hash_NodeSet(NodeSet *ns) { unsigned long hash = 5381; for (NodeSet::iterator i = ns->begin(); i != ns->end(); i++) { hash = ((hash << 5) + hash) + (unsigned long)*i; } return hash; } /** * label_nodes - label the node positions for pretty-printing debug output * * TODO: separate - node labels should be separate and optional, if not * present pretty printing should use Node address */ void label_nodes(Node *root) { int nodes = 1; for (depth_first_traversal i(root); i; i++) i->label = nodes++; } /** * Text-dump the syntax tree (for debugging). */ void Node::dump_syntax_tree(ostream &os) { for (depth_first_traversal i(this); i; i++) { os << i->label << '\t'; if ((*i)->child[0] == 0) os << **i << '\t' << (*i)->followpos << endl; else { if ((*i)->child[1] == 0) os << (*i)->child[0]->label << **i; else os << (*i)->child[0]->label << **i << (*i)->child[1]->label; os << '\t' << (*i)->firstpos << (*i)->lastpos << endl; } } os << endl; } /* * Normalize the regex parse tree for factoring and cancelations. Normalization * reorganizes internal (alt and cat) nodes into a fixed "normalized" form that * simplifies factoring code, in that it produces a canonicalized form for * the direction being normalized so that the factoring code does not have * to consider as many cases. * * left normalization (dir == 0) uses these rules * (E | a) -> (a | E) * (a | b) | c -> a | (b | c) * (ab)c -> a(bc) * * right normalization (dir == 1) uses the same rules but reversed * (a | E) -> (E | a) * a | (b | c) -> (a | b) | c * a(bc) -> (ab)c * * Note: This is written iteratively for a given node (the top node stays * fixed and the children are rotated) instead of recursively. * For a given node under examination rotate over nodes from * dir to !dir. Until no dir direction node meets the criterial. * Then recurse to the children (which will have a different node type) * to make sure they are normalized. * Normalization of a child node is guarenteed to not affect the * normalization of the parent. * * For cat nodes the depth first traverse order is guarenteed to be * maintained. This is not necessary for altnodes. * * Eg. For left normalization * * |1 |1 * / \ / \ * |2 T -> a |2 * / \ / \ * |3 c b |3 * / \ / \ * a b c T * */ static void rotate_node(Node *t, int dir) { // (a | b) | c -> a | (b | c) // (ab)c -> a(bc) Node *left = t->child[dir]; t->child[dir] = left->child[dir]; left->child[dir] = left->child[!dir]; left->child[!dir] = t->child[!dir]; t->child[!dir] = left; } /* return False if no work done */ int TwoChildNode::normalize_eps(int dir) { if ((&epsnode == child[dir]) && (&epsnode != child[!dir])) { // (E | a) -> (a | E) // Ea -> aE // Test for E | (E | E) and E . (E . E) which will // result in an infinite loop Node *c = child[!dir]; if (dynamic_cast(c) && &epsnode == c->child[dir] && &epsnode == c->child[!dir]) { c->release(); c = &epsnode; } child[!dir] = child[dir]; child[dir] = c; return 1; } return 0; } void CatNode::normalize(int dir) { for (;;) { if (normalize_eps(dir)) { continue; } else if (dynamic_cast(child[dir])) { // (ab)c -> a(bc) rotate_node(this, dir); } else { break; } } if (child[dir]) child[dir]->normalize(dir); if (child[!dir]) child[!dir]->normalize(dir); } void AltNode::normalize(int dir) { for (;;) { if (normalize_eps(dir)) { continue; } else if (dynamic_cast(child[dir])) { // (a | b) | c -> a | (b | c) rotate_node(this, dir); } else if (dynamic_cast(child[dir]) && dynamic_cast(child[!dir])) { // [a] | b -> b | [a] Node *c = child[dir]; child[dir] = child[!dir]; child[!dir] = c; } else { break; } } if (child[dir]) child[dir]->normalize(dir); if (child[!dir]) child[!dir]->normalize(dir); } //charset conversion is disabled for now, //it hinders tree optimization in some cases, so it need to be either //done post optimization, or have extra factoring rules added #if 0 static Node *merge_charset(Node *a, Node *b) { if (dynamic_cast(a) && dynamic_cast(b)) { Chars chars; chars.insert(dynamic_cast(a)->c); chars.insert(dynamic_cast(b)->c); CharSetNode *n = new CharSetNode(chars); return n; } else if (dynamic_cast(a) && dynamic_cast(b)) { Chars *chars = &dynamic_cast(b)->chars; chars->insert(dynamic_cast(a)->c); return b; } else if (dynamic_cast(a) && dynamic_cast(b)) { Chars *from = &dynamic_cast(a)->chars; Chars *to = &dynamic_cast(b)->chars; for (Chars::iterator i = from->begin(); i != from->end(); i++) to->insert(*i); return b; } //return ???; } static Node *alt_to_charsets(Node *t, int dir) { /* Node *first = NULL; Node *p = t; Node *i = t; for (;dynamic_cast(i);) { if (dynamic_cast(i->child[dir]) || dynamic_cast(i->child[dir])) { if (!first) { first = i; p = i; i = i->child[!dir]; } else { first->child[dir] = merge_charset(first->child[dir], i->child[dir]); p->child[!dir] = i->child[!dir]; Node *tmp = i; i = tmp->child[!dir]; tmp->child[!dir] = NULL; tmp->release(); } } else { p = i; i = i->child[!dir]; } } // last altnode of chain check other dir as well if (first && (dynamic_cast(i) || dynamic_cast(i))) { } */ /* if (dynamic_cast(t->child[dir]) || dynamic_cast(t->child[dir])) char_test = true; (char_test && (dynamic_cast(i->child[dir]) || dynamic_cast(i->child[dir])))) { */ return t; } #endif static Node *basic_alt_factor(Node *t, int dir) { if (!dynamic_cast(t)) return t; if (t->child[dir]->eq(t->child[!dir])) { // (a | a) -> a Node *tmp = t->child[dir]; t->child[dir] = NULL; t->release(); return tmp; } // (ab) | (ac) -> a(b|c) if (dynamic_cast(t->child[dir]) && dynamic_cast(t->child[!dir]) && t->child[dir]->child[dir]->eq(t->child[!dir]->child[dir])) { // (ab) | (ac) -> a(b|c) Node *left = t->child[dir]; Node *right = t->child[!dir]; t->child[dir] = left->child[!dir]; t->child[!dir] = right->child[!dir]; right->child[!dir] = NULL; right->release(); left->child[!dir] = t; return left; } // a | (ab) -> a (E | b) -> a (b | E) if (dynamic_cast(t->child[!dir]) && t->child[dir]->eq(t->child[!dir]->child[dir])) { Node *c = t->child[!dir]; t->child[dir]->release(); t->child[dir] = c->child[!dir]; t->child[!dir] = &epsnode; c->child[!dir] = t; return c; } // ab | (a) -> a (b | E) if (dynamic_cast(t->child[dir]) && t->child[dir]->child[dir]->eq(t->child[!dir])) { Node *c = t->child[dir]; t->child[!dir]->release(); t->child[dir] = c->child[!dir]; t->child[!dir] = &epsnode; c->child[!dir] = t; return c; } return t; } static Node *basic_simplify(Node *t, int dir) { if (dynamic_cast(t) && &epsnode == t->child[!dir]) { // aE -> a Node *tmp = t->child[dir]; t->child[dir] = NULL; t->release(); return tmp; } return basic_alt_factor(t, dir); } /* * assumes a normalized tree. reductions shown for left normalization * aE -> a * (a | a) -> a ** factoring patterns * a | (a | b) -> (a | b) * a | (ab) -> a (E | b) -> a (b | E) * (ab) | (ac) -> a(b|c) * * returns t - if no simplifications were made * a new root node - if simplifications were made */ Node *simplify_tree_base(Node *t, int dir, bool &mod) { if (dynamic_cast(t)) return t; for (int i = 0; i < 2; i++) { if (t->child[i]) { Node *c = simplify_tree_base(t->child[i], dir, mod); if (c != t->child[i]) { t->child[i] = c; mod = true; } } } // only iterate on loop if modification made for (;; mod = true) { Node *tmp = basic_simplify(t, dir); if (tmp != t) { t = tmp; continue; } /* all tests after this must meet 2 alt node condition */ if (!dynamic_cast(t) || !dynamic_cast(t->child[!dir])) break; // a | (a | b) -> (a | b) // a | (b | (c | a)) -> (b | (c | a)) Node *p = t; Node *i = t->child[!dir]; for (; dynamic_cast(i); p = i, i = i->child[!dir]) { if (t->child[dir]->eq(i->child[dir])) { Node *tmp = t->child[!dir]; t->child[!dir] = NULL; t->release(); t = tmp; continue; } } // last altnode of chain check other dir as well if (t->child[dir]->eq(p->child[!dir])) { Node *tmp = t->child[!dir]; t->child[!dir] = NULL; t->release(); t = tmp; continue; } //exact match didn't work, try factoring front //a | (ac | (ad | () -> (a (E | c)) | (...) //ab | (ac | (...)) -> (a (b | c)) | (...) //ab | (a | (...)) -> (a (b | E)) | (...) Node *pp; int count = 0; Node *subject = t->child[dir]; Node *a = subject; if (dynamic_cast(subject)) a = subject->child[dir]; for (pp = p = t, i = t->child[!dir]; dynamic_cast(i);) { if ((dynamic_cast(i->child[dir]) && a->eq(i->child[dir]->child[dir])) || (a->eq(i->child[dir]))) { // extract matching alt node p->child[!dir] = i->child[!dir]; i->child[!dir] = subject; subject = basic_simplify(i, dir); if (dynamic_cast(subject)) a = subject->child[dir]; else a = subject; i = p->child[!dir]; count++; } else { pp = p; p = i; i = i->child[!dir]; } } // last altnode in chain check other dir as well if ((dynamic_cast(i) && a->eq(i->child[dir])) || (a->eq(i))) { count++; if (t == p) { t->child[dir] = subject; t = basic_simplify(t, dir); } else { t->child[dir] = p->child[dir]; p->child[dir] = subject; pp->child[!dir] = basic_simplify(p, dir); } } else { t->child[dir] = i; p->child[!dir] = subject; } if (count == 0) break; } return t; } int debug_tree(Node *t) { int nodes = 1; if (!dynamic_cast(t)) { if (t->child[0]) nodes += debug_tree(t->child[0]); if (t->child[1]) nodes += debug_tree(t->child[1]); } return nodes; } static void count_tree_nodes(Node *t, struct node_counts *counts) { if (dynamic_cast(t)) { counts->alt++; count_tree_nodes(t->child[0], counts); count_tree_nodes(t->child[1], counts); } else if (dynamic_cast(t)) { counts->cat++; count_tree_nodes(t->child[0], counts); count_tree_nodes(t->child[1], counts); } else if (dynamic_cast(t)) { counts->plus++; count_tree_nodes(t->child[0], counts); } else if (dynamic_cast(t)) { counts->star++; count_tree_nodes(t->child[0], counts); } else if (dynamic_cast(t)) { counts->charnode++; } else if (dynamic_cast(t)) { counts->any++; } else if (dynamic_cast(t)) { counts->charset++; } else if (dynamic_cast(t)) { counts->notcharset++; } } #include "stdio.h" #include "stdint.h" #include "apparmor_re.h" Node *simplify_tree(Node *t, dfaflags_t flags) { bool update; if (flags & DFA_DUMP_TREE_STATS) { struct node_counts counts = { 0, 0, 0, 0, 0, 0, 0, 0 }; count_tree_nodes(t, &counts); fprintf(stderr, "expr tree: c %d, [] %d, [^] %d, | %d, + %d, * %d, . %d, cat %d\n", counts.charnode, counts.charset, counts.notcharset, counts.alt, counts.plus, counts.star, counts.any, counts.cat); } do { update = false; //default to right normalize first as this reduces the number //of trailing nodes which might follow an internal * //or **, which is where state explosion can happen //eg. in one test this makes the difference between // the dfa having about 7 thousands states, // and it having about 1.25 million states int dir = 1; if (flags & DFA_CONTROL_TREE_LEFT) dir = 0; for (int count = 0; count < 2; count++) { bool modified; do { modified = false; if (flags & DFA_CONTROL_TREE_NORMAL) t->normalize(dir); t = simplify_tree_base(t, dir, modified); if (modified) update = true; } while (modified); if (flags & DFA_CONTROL_TREE_LEFT) dir++; else dir--; } } while (update); if (flags & DFA_DUMP_TREE_STATS) { struct node_counts counts = { 0, 0, 0, 0, 0, 0, 0, 0 }; count_tree_nodes(t, &counts); fprintf(stderr, "simplified expr tree: c %d, [] %d, [^] %d, | %d, + %d, * %d, . %d, cat %d\n", counts.charnode, counts.charset, counts.notcharset, counts.alt, counts.plus, counts.star, counts.any, counts.cat); } return t; } /** * Flip the children of all cat nodes. This causes strings to be matched * back-forth. */ void flip_tree(Node *node) { for (depth_first_traversal i(node); i; i++) { if (CatNode *cat = dynamic_cast(*i)) { swap(cat->child[0], cat->child[1]); } } } void dump_regex_rec(ostream &os, Node *tree) { if (tree->child[0]) dump_regex_rec(os, tree->child[0]); os << *tree; if (tree->child[1]) dump_regex_rec(os, tree->child[1]); } void dump_regex(ostream &os, Node *tree) { dump_regex_rec(os, tree); os << endl; } apparmor-2.13.3/parser/libapparmor_re/parse.y0000644000175000017500000001053313502024172017005 0ustar jjjj/* * (C) 2006, 2007 Andreas Gruenbacher * Copyright (c) 2003-2008 Novell, Inc. (All rights reserved) * Copyright 2009-2010 Canonical Ltd. * * The libapparmor library is licensed under the terms of the GNU * Lesser General Public License, version 2.1. Please see the file * COPYING.LGPL. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * * Parsing of regular expression into expression trees as implemented in * expr-tree */ %{ /* #define DEBUG_TREE */ #include "expr-tree.h" %} %union { char c; Node *node; Chars *cset; } %{ void regex_error(Node **, const char *, const char *); #define YYLEX_PARAM &text int regex_lex(YYSTYPE *, const char **); static inline Chars *insert_char(Chars* cset, uchar a) { cset->insert(a); return cset; } static inline Chars* insert_char_range(Chars* cset, uchar a, uchar b) { if (a > b) swap(a, b); for (uchar i = a; i <= b; i++) cset->insert(i); return cset; } %} %define api.pure /* %error-verbose */ %lex-param {YYLEX_PARAM} %parse-param {Node **root} %parse-param {const char *text} %name-prefix "regex_" %token CHAR %type regex_char cset_char1 cset_char cset_charN %type charset cset_chars %type regex expr terms0 terms qterm term /** * Note: destroy all nodes upon failure, but *not* the start symbol once * parsing succeeds! */ %destructor { $$->release(); } expr terms0 terms qterm term %% /* FIXME: Does not parse "[--]", "[---]", "[^^-x]". I don't actually know which precise grammer Perl regexs use, and rediscovering that is proving to be painful. */ regex : /* empty */ { *root = $$ = &epsnode; } | expr { *root = $$ = $1; } ; expr : terms | expr '|' terms0 { $$ = new AltNode($1, $3); } | '|' terms0 { $$ = new AltNode(&epsnode, $2); } ; terms0 : /* empty */ { $$ = &epsnode; } | terms ; terms : qterm | terms qterm { $$ = new CatNode($1, $2); } ; qterm : term | term '*' { $$ = new StarNode($1); } | term '+' { $$ = new PlusNode($1); } ; term : '.' { $$ = new AnyCharNode; } | regex_char { $$ = new CharNode($1); } | '[' charset ']' { $$ = new CharSetNode(*$2); delete $2; } | '[' '^' charset ']' { $$ = new NotCharSetNode(*$3); delete $3; } | '[' '^' '^' cset_chars ']' { $4->insert('^'); $$ = new NotCharSetNode(*$4); delete $4; } | '(' regex ')' { $$ = $2; } ; regex_char : CHAR | '^' { $$ = '^'; } | '-' { $$ = '-'; } | ']' { $$ = ']'; } ; charset : cset_char1 cset_chars { $$ = insert_char($2, $1); } | cset_char1 '-' cset_charN cset_chars { $$ = insert_char_range($4, $1, $3); } ; cset_chars : /* nothing */ { $$ = new Chars; } | cset_chars cset_charN { $$ = insert_char($1, $2); } | cset_chars cset_charN '-' cset_charN { $$ = insert_char_range($1, $2, $4); } ; cset_char1 : cset_char | ']' { $$ = ']'; } | '-' { $$ = '-'; } ; cset_charN : cset_char | '^' { $$ = '^'; } ; cset_char : CHAR | '[' { $$ = '['; } | '*' { $$ = '*'; } | '+' { $$ = '+'; } | '.' { $$ = '.'; } | '|' { $$ = '|'; } | '(' { $$ = '('; } | ')' { $$ = ')'; } ; %% #include "../lib.h" int regex_lex(YYSTYPE *val, const char **pos) { int tmp; val->c = **pos; switch(*(*pos)++) { case '\0': (*pos)--; return 0; case '*': case '+': case '.': case '|': case '^': case '-': case '[': case ']': case '(' : case ')': return *(*pos - 1); case '\\': tmp = str_escseq(pos, "*+.|^$-[](){}"); if (tmp == -1) { /* bad escape sequence, just skip it for now, that * is output \\ followed by the invalid esc seq * TODO: output error message */ val->c = '\\'; (*pos)--; } else val->c = tmp; break; } return CHAR; } void regex_error(Node ** __attribute__((unused)), const char *text __attribute__((unused)), const char *error __attribute__((unused))) { /* We don't want the library to print error messages. */ } apparmor-2.13.3/parser/libapparmor_re/aare_rules.h0000644000175000017500000000554513502024172020003 0ustar jjjj/* * (C) 2006, 2007 Andreas Gruenbacher * Copyright (c) 2003-2008 Novell, Inc. (All rights reserved) * Copyright 2009-2012 Canonical Ltd. * * The libapparmor library is licensed under the terms of the GNU * Lesser General Public License, version 2.1. Please see the file * COPYING.LGPL. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * * Wrapper around the dfa to convert aa rules into a dfa */ #ifndef __LIBAA_RE_RULES_H #define __LIBAA_RE_RULES_H #include #include "apparmor_re.h" #include "expr-tree.h" class UniquePerm { public: bool deny; bool exact_match; uint32_t perms; uint32_t audit; bool operator<(UniquePerm const &rhs)const { if (deny == rhs.deny) { if (exact_match == rhs.exact_match) { if (perms == rhs.perms) return audit < rhs.audit; return perms < rhs.perms; } return exact_match; } return deny; } }; class UniquePermsCache { public: typedef map UniquePermMap; typedef UniquePermMap::iterator iterator; UniquePermMap nodes; UniquePermsCache(void) { }; ~UniquePermsCache() { clear(); } void clear() { for (iterator i = nodes.begin(); i != nodes.end(); i++) { delete i->second; } nodes.clear(); } Node *insert(bool deny, uint32_t perms, uint32_t audit, bool exact_match) { UniquePerm tmp = { deny, exact_match, perms, audit }; iterator res = nodes.find(tmp); if (res == nodes.end()) { Node *node; if (deny) node = new DenyMatchFlag(perms, audit); else if (exact_match) node = new ExactMatchFlag(perms, audit); else node = new MatchFlag(perms, audit); pair val = nodes.insert(make_pair(tmp, node)); if (val.second == false) return val.first->second; return node; } return res->second; } }; typedef std::map PermExprMap; class aare_rules { Node *root; void add_to_rules(Node *tree, Node *perms); UniquePermsCache unique_perms; PermExprMap expr_map; public: int reverse; int rule_count; aare_rules(void): root(NULL), unique_perms(), expr_map(), reverse(0), rule_count(0) { }; aare_rules(int reverse): root(NULL), unique_perms(), expr_map(), reverse(reverse), rule_count(0) { }; ~aare_rules(); bool add_rule(const char *rule, int deny, uint32_t perms, uint32_t audit, dfaflags_t flags); bool add_rule_vec(int deny, uint32_t perms, uint32_t audit, int count, const char **rulev, dfaflags_t flags); void *create_dfa(size_t *size, int *min_match_len, dfaflags_t flags); }; #endif /* __LIBAA_RE_RULES_H */ apparmor-2.13.3/parser/libapparmor_re/parse.h0000644000175000017500000000166713502024172016774 0ustar jjjj/* * (C) 2006, 2007 Andreas Gruenbacher * Copyright (c) 2003-2008 Novell, Inc. (All rights reserved) * Copyright 2009-2010 Canonical Ltd. * * The libapparmor library is licensed under the terms of the GNU * Lesser General Public License, version 2.1. Please see the file * COPYING.LGPL. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * * Parsing of regular expression into expression trees as implemented in * expr-tree */ #ifndef __LIBAA_RE_PARSE_H #define __LIBAA_RE_PARSE_H int regex_parse(Node **tree, const char *rule); #endif /* __LIBAA_RE_PARSE_H */ apparmor-2.13.3/parser/libapparmor_re/chfa.h0000644000175000017500000000350213502024172016551 0ustar jjjj/* * (C) 2006, 2007 Andreas Gruenbacher * Copyright (c) 2003-2008 Novell, Inc. (All rights reserved) * Copyright 2009-2012 Canonical Ltd. * * The libapparmor library is licensed under the terms of the GNU * Lesser General Public License, version 2.1. Please see the file * COPYING.LGPL. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * * Create a compressed hfa (chfa) from and hfa */ #ifndef __LIBAA_RE_CHFA_H #define __LIBAA_RE_CHFA_H #include #include #include "hfa.h" #define BASE32_FLAGS 0xff000000 #define DiffEncodeBit32 0x80000000 #define base_mask_size(X) ((X) & ~BASE32_FLAGS) using namespace std; class CHFA { typedef vector > DefaultBase; typedef vector > NextCheck; public: CHFA(DFA &dfa, map &eq, dfaflags_t flags); void dump(ostream & os); void flex_table(ostream &os, const char *name); void init_free_list(vector > &free_list, size_t prev, size_t start); bool fits_in(vector > &free_list, size_t base, StateTrans &cases); void insert_state(vector > &free_list, State *state, DFA &dfa); private: vector accept; vector accept2; DefaultBase default_base; NextCheck next_check; map num; map &eq; uchar max_eq; size_t first_free; unsigned int chfaflags; }; #endif /* __LIBAA_RE_CHFA_H */ apparmor-2.13.3/parser/libapparmor_re/hfa.h0000644000175000017500000002053513502024172016413 0ustar jjjj/* * (C) 2006, 2007 Andreas Gruenbacher * Copyright (c) 2003-2008 Novell, Inc. (All rights reserved) * Copyright 2009-2012 Canonical Ltd. * * The libapparmor library is licensed under the terms of the GNU * Lesser General Public License, version 2.1. Please see the file * COPYING.LGPL. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * * Base of implementation based on the Lexical Analysis chapter of: * Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman: * Compilers: Principles, Techniques, and Tools (The "Dragon Book"), * Addison-Wesley, 1986. */ #ifndef __LIBAA_RE_HFA_H #define __LIBAA_RE_HFA_H #include #include #include #include #include #include "expr-tree.h" #define DiffEncodeFlag 1 class State; typedef map StateTrans; typedef list Partition; #include "../immunix.h" class perms_t { public: perms_t(void) throw(int): allow(0), deny(0), audit(0), quiet(0), exact(0) { }; bool is_accept(void) { return (allow | audit | quiet); } void dump(ostream &os) { os << " (0x " << hex << allow << "/" << deny << "/" << audit << "/" << quiet << ')' << dec; } void clear(void) { allow = deny = audit = quiet = 0; } void add(perms_t &rhs) { deny |= rhs.deny; if (!is_merged_x_consistent(allow & ALL_USER_EXEC, rhs.allow & ALL_USER_EXEC)) { if ((exact & AA_USER_EXEC_TYPE) && !(rhs.exact & AA_USER_EXEC_TYPE)) { /* do nothing */ } else if ((rhs.exact & AA_USER_EXEC_TYPE) && !(exact & AA_USER_EXEC_TYPE)) { allow = (allow & ~AA_USER_EXEC_TYPE) | (rhs.allow & AA_USER_EXEC_TYPE); } else throw 1; } else allow |= rhs.allow & AA_USER_EXEC_TYPE; if (!is_merged_x_consistent(allow & ALL_OTHER_EXEC, rhs.allow & ALL_OTHER_EXEC)) { if ((exact & AA_OTHER_EXEC_TYPE) && !(rhs.exact & AA_OTHER_EXEC_TYPE)) { /* do nothing */ } else if ((rhs.exact & AA_OTHER_EXEC_TYPE) && !(exact & AA_OTHER_EXEC_TYPE)) { allow = (allow & ~AA_OTHER_EXEC_TYPE) | (rhs.allow & AA_OTHER_EXEC_TYPE); } else throw 1; } else allow |= rhs.allow & AA_OTHER_EXEC_TYPE; allow = (allow | (rhs.allow & ~ALL_AA_EXEC_TYPE)); audit |= rhs.audit; quiet = (quiet | rhs.quiet); /* if (exec & AA_USER_EXEC_TYPE && (exec & AA_USER_EXEC_TYPE) != (allow & AA_USER_EXEC_TYPE)) throw 1; if (exec & AA_OTHER_EXEC_TYPE && (exec & AA_OTHER_EXEC_TYPE) != (allow & AA_OTHER_EXEC_TYPE)) throw 1; */ } int apply_and_clear_deny(void) { if (deny) { allow &= ~deny; quiet &= deny; deny = 0; return !is_accept(); } return 0; } bool operator<(perms_t const &rhs)const { if (allow < rhs.allow) return allow < rhs.allow; if (deny < rhs.deny) return deny < rhs.deny; if (audit < rhs.audit) return audit < rhs.audit; return quiet < rhs.quiet; } uint32_t allow, deny, audit, quiet, exact; }; int accept_perms(NodeSet *state, perms_t &perms); /* * ProtoState - NodeSet and ancillery information used to create a state */ class ProtoState { public: hashedNodeVec *nnodes; NodeSet *anodes; /* init is used instead of a constructor because ProtoState is used * in a union */ void init(hashedNodeVec *n, NodeSet *a = NULL) { nnodes = n; anodes = a; } bool operator<(ProtoState const &rhs)const { if (nnodes == rhs.nnodes) return anodes < rhs.anodes; return nnodes < rhs.nnodes; } unsigned long size(void) { if (anodes) return nnodes->size() + anodes->size(); return nnodes->size(); } }; /* Temporary state structure used when building differential encoding * @parents - set of states that have transitions to this state * @depth - level in the DAG * @state - back reference to state this DAG entry belongs * @rel - state that this state is relative to for differential encoding */ struct DiffDag { Partition parents; int depth; State *state; State *rel; }; /* * State - DFA individual state information * label: a unique label to identify the state used for pretty printing * the non-matching state is setup to have label == 0 and * the start state is setup to have label == 1 * audit: the audit permission mask for the state * accept: the accept permissions for the state * trans: set of transitions from this state * otherwise: the default state for transitions not in @trans * parition: Is a temporary work variable used during dfa minimization. * it can be replaced with a map, but that is slower and uses more * memory. * proto: Is a temporary work variable used during dfa creation. It can * be replaced by using the nodemap, but that is slower */ class State { public: State(int l, ProtoState &n, State *other) throw(int): label(l), flags(0), perms(), trans() { int error; if (other) otherwise = other; else otherwise = this; proto = n; /* Compute permissions associated with the State. */ error = accept_perms(n.anodes, perms); if (error) { //cerr << "Failing on accept perms " << error << "\n"; throw error; } }; State *next(uchar c) { State *state = this; do { StateTrans::iterator i = state->trans.find(c); if (i != state->trans.end()) return i->second; if (!(state->flags & DiffEncodeFlag)) return state->otherwise; state = state->otherwise; } while (state); /* never reached */ assert(0); return NULL; } int diff_weight(State *rel); int make_relative(State *rel); void flatten_relative(void); int apply_and_clear_deny(void) { return perms.apply_and_clear_deny(); } int label; int flags; perms_t perms; StateTrans trans; State *otherwise; /* temp storage for State construction */ union { Partition *partition; /* used during minimization */ ProtoState proto; /* used during creation */ DiffDag *diff; /* used during diff encoding */ }; }; ostream &operator<<(ostream &os, const State &state); class NodeMap: public CacheStats { public: typedef map::iterator iterator; iterator begin() { return cache.begin(); } iterator end() { return cache.end(); } map cache; NodeMap(void): cache() { }; ~NodeMap() { clear(); }; virtual unsigned long size(void) const { return cache.size(); } void clear() { cache.clear(); CacheStats::clear(); } pair insert(ProtoState &proto, State *state) { pair uniq; uniq = cache.insert(make_pair(proto, state)); if (uniq.second == false) { dup++; } else { sum += proto.size(); if (proto.size() > max) max = proto.size(); } return uniq; } }; /* Transitions in the DFA. */ class DFA { void dump_node_to_dfa(void); State *add_new_state(NodeSet *nodes, State *other); State *add_new_state(NodeSet *anodes, NodeSet *nnodes, State *other); void update_state_transitions(State *state); void process_work_queue(const char *header, dfaflags_t); void dump_diff_chain(ostream &os, map &relmap, Partition &chain, State *state, unsigned int &count, unsigned int &total, unsigned int &max); /* temporary values used during computations */ NodeCache anodes_cache; NodeVecCache nnodes_cache; NodeMap node_map; list work_queue; public: DFA(Node *root, dfaflags_t flags); virtual ~DFA(); State *match_len(State *state, const char *str, size_t len); State *match_until(State *state, const char *str, const char term); State *match(const char *str); void remove_unreachable(dfaflags_t flags); bool same_mappings(State *s1, State *s2); void minimize(dfaflags_t flags); int apply_and_clear_deny(void); void diff_encode(dfaflags_t flags); void undiff_encode(void); void dump_diff_encode(ostream &os); void dump(ostream &os); void dump_dot_graph(ostream &os); void dump_uniq_perms(const char *s); map equivalence_classes(dfaflags_t flags); void apply_equivalence_classes(map &eq); unsigned int diffcount; Node *root; State *nonmatching, *start; Partition states; }; void dump_equivalence_classes(ostream &os, map &eq); #endif /* __LIBAA_RE_HFA_H */ apparmor-2.13.3/parser/libapparmor_re/chfa.cc0000644000175000017500000003027413502024172016715 0ustar jjjj/* * (C) 2006, 2007 Andreas Gruenbacher * Copyright (c) 2003-2008 Novell, Inc. (All rights reserved) * Copyright 2009-2012 Canonical Ltd. * * The libapparmor library is licensed under the terms of the GNU * Lesser General Public License, version 2.1. Please see the file * COPYING.LGPL. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * * Create a compressed hfa from and hfa */ #include #include #include #include #include #include #include #include #include "hfa.h" #include "chfa.h" #include "../immunix.h" #include "flex-tables.h" void CHFA::init_free_list(vector > &free_list, size_t prev, size_t start) { for (size_t i = start; i < free_list.size(); i++) { if (prev) free_list[prev].second = i; free_list[i].first = prev; prev = i; } free_list[free_list.size() - 1].second = 0; } /** * new Construct the transition table. */ CHFA::CHFA(DFA &dfa, map &eq, dfaflags_t flags): eq(eq) { if (flags & DFA_DUMP_TRANS_PROGRESS) fprintf(stderr, "Compressing HFA:\r"); if (dfa.diffcount) chfaflags = YYTH_FLAG_DIFF_ENCODE; else chfaflags = 0; if (eq.empty()) max_eq = 255; else { max_eq = 0; for (map::iterator i = eq.begin(); i != eq.end(); i++) { if (i->second > max_eq) max_eq = i->second; } } /* Do initial setup adding up all the transitions and sorting by * transition count. */ size_t optimal = 2; multimap order; vector > free_list; for (Partition::iterator i = dfa.states.begin(); i != dfa.states.end(); i++) { if (*i == dfa.start || *i == dfa.nonmatching) continue; optimal += (*i)->trans.size(); if (flags & DFA_CONTROL_TRANS_HIGH) { size_t range = 0; if ((*i)->trans.size()) range = (*i)->trans.rbegin()->first - (*i)->trans.begin()->first; size_t ord = ((256 - (*i)->trans.size()) << 8) | (256 - range); /* reverse sort by entry count, most entries first */ order.insert(make_pair(ord, *i)); } } /* Insert the dummy nonmatching transition by hand */ next_check.push_back(make_pair(dfa.nonmatching, dfa.nonmatching)); default_base.push_back(make_pair(dfa.nonmatching, 0)); num.insert(make_pair(dfa.nonmatching, num.size())); accept.resize(max(dfa.states.size(), (size_t) 2)); accept2.resize(max(dfa.states.size(), (size_t) 2)); next_check.resize(max(optimal, (size_t) 256)); free_list.resize(next_check.size()); accept[0] = 0; accept2[0] = 0; first_free = 1; init_free_list(free_list, 0, 1); insert_state(free_list, dfa.start, dfa); accept[1] = 0; accept2[1] = 0; num.insert(make_pair(dfa.start, num.size())); int count = 2; if (!(flags & DFA_CONTROL_TRANS_HIGH)) { for (Partition::iterator i = dfa.states.begin(); i != dfa.states.end(); i++) { if (*i != dfa.nonmatching && *i != dfa.start) { insert_state(free_list, *i, dfa); accept[num.size()] = (*i)->perms.allow; accept2[num.size()] = PACK_AUDIT_CTL((*i)->perms.audit, (*i)->perms.quiet & (*i)->perms.deny); num.insert(make_pair(*i, num.size())); } if (flags & (DFA_DUMP_TRANS_PROGRESS)) { count++; if (count % 100 == 0) fprintf(stderr, "\033[2KCompressing trans table: insert state: %d/%zd\r", count, dfa.states.size()); } } } else { for (multimap::iterator i = order.begin(); i != order.end(); i++) { if (i->second != dfa.nonmatching && i->second != dfa.start) { insert_state(free_list, i->second, dfa); accept[num.size()] = i->second->perms.allow; accept2[num.size()] = PACK_AUDIT_CTL(i->second->perms.audit, i->second->perms.quiet & i->second->perms.deny); num.insert(make_pair(i->second, num.size())); } if (flags & (DFA_DUMP_TRANS_PROGRESS)) { count++; if (count % 100 == 0) fprintf(stderr, "\033[2KCompressing trans table: insert state: %d/%zd\r", count, dfa.states.size()); } } } if (flags & (DFA_DUMP_TRANS_STATS | DFA_DUMP_TRANS_PROGRESS)) { ssize_t size = 4 * next_check.size() + 6 * dfa.states.size(); fprintf(stderr, "\033[2KCompressed trans table: states %zd, next/check %zd, optimal next/check %zd avg/state %.2f, compression %zd/%zd = %.2f %%\n", dfa.states.size(), next_check.size(), optimal, (float)next_check.size() / (float)dfa.states.size(), size, 512 * dfa.states.size(), 100.0 - ((float)size * 100.0 /(float)(512 * dfa.states.size()))); } } /** * Does fit into position of the transition table? */ bool CHFA::fits_in(vector > &free_list __attribute__ ((unused)), size_t pos, StateTrans &trans) { size_t c, base = pos - trans.begin()->first; for (StateTrans::iterator i = trans.begin(); i != trans.end(); i++) { c = base + i->first; /* if it overflows the next_check array it fits in as we will * resize */ if (c >= next_check.size()) return true; if (next_check[c].second) return false; } return true; } /** * Insert of into the transition table. */ void CHFA::insert_state(vector > &free_list, State *from, DFA &dfa) { State *default_state = dfa.nonmatching; size_t base = 0; int resize; StateTrans &trans = from->trans; size_t c = trans.begin()->first; size_t prev = 0; size_t x = first_free; if (from->otherwise) default_state = from->otherwise; if (trans.empty()) goto do_insert; repeat: resize = 0; /* get the first free entry that won't underflow */ while (x && (x < c)) { prev = x; x = free_list[x].second; } /* try inserting until we succeed. */ while (x && !fits_in(free_list, x, trans)) { prev = x; x = free_list[x].second; } if (!x) { resize = 256 - trans.begin()->first; x = free_list.size(); /* set prev to last free */ } else if (x + 255 - trans.begin()->first >= next_check.size()) { resize = (255 - trans.begin()->first - (next_check.size() - 1 - x)); for (size_t y = x; y; y = free_list[y].second) prev = y; } if (resize) { /* expand next_check and free_list */ size_t old_size = free_list.size(); next_check.resize(next_check.size() + resize); free_list.resize(free_list.size() + resize); init_free_list(free_list, prev, old_size); if (!first_free) first_free = old_size;; if (x == old_size) goto repeat; } base = x - c; for (StateTrans::iterator j = trans.begin(); j != trans.end(); j++) { next_check[base + j->first] = make_pair(j->second, from); size_t prev = free_list[base + j->first].first; size_t next = free_list[base + j->first].second; if (prev) free_list[prev].second = next; if (next) free_list[next].first = prev; if (base + j->first == first_free) first_free = next; } do_insert: if (from->flags & DiffEncodeFlag) base |= DiffEncodeBit32; default_base.push_back(make_pair(default_state, base)); } /** * Text-dump the transition table (for debugging). */ void CHFA::dump(ostream &os) { map st; for (map::iterator i = num.begin(); i != num.end(); i++) { st.insert(make_pair(i->second, i->first)); } os << "size=" << default_base.size() << " (accept, default, base): {state} -> {default state}" << "\n"; for (size_t i = 0; i < default_base.size(); i++) { os << i << ": "; os << "(" << accept[i] << ", " << num[default_base[i].first] << ", " << default_base[i].second << ")"; if (st[i]) os << " " << *st[i]; if (default_base[i].first) os << " -> " << *default_base[i].first; os << "\n"; } os << "size=" << next_check.size() << " (next, check): {check state} -> {next state} : offset from base\n"; for (size_t i = 0; i < next_check.size(); i++) { if (!next_check[i].second) continue; os << i << ": "; if (next_check[i].second) { os << "(" << num[next_check[i].first] << ", " << num[next_check[i].second] << ")" << " " << *next_check[i].second << " -> " << *next_check[i].first << ": "; size_t offs = i - base_mask_size(default_base[num[next_check[i].second]].second); if (eq.size()) os << offs; else os << (uchar) offs; } os << "\n"; } } /** * Create a flex-style binary dump of the DFA tables. The table format * was partly reverse engineered from the flex sources and from * examining the tables that flex creates with its --tables-file option. * (Only the -Cf and -Ce formats are currently supported.) */ #define YYTH_REGEX_MAGIC 0x1B5E783D static inline size_t pad64(size_t i) { return (i + (size_t) 7) & ~(size_t) 7; } string fill64(size_t i) { const char zeroes[8] = { }; string fill(zeroes, (i & 7) ? 8 - (i & 7) : 0); return fill; } template size_t flex_table_size(Iter pos, Iter end) { return pad64(sizeof(struct table_header) + sizeof(*pos) * (end - pos)); } template void write_flex_table(ostream &os, int id, Iter pos, Iter end) { struct table_header td = { 0, 0, 0, 0 }; size_t size = end - pos; td.td_id = htons(id); td.td_flags = htons(sizeof(*pos)); td.td_lolen = htonl(size); os.write((char *)&td, sizeof(td)); for (; pos != end; ++pos) { switch (sizeof(*pos)) { case 4: os.put((char)(*pos >> 24)); os.put((char)(*pos >> 16)); case 2: os.put((char)(*pos >> 8)); case 1: os.put((char)*pos); } } os << fill64(sizeof(td) + sizeof(*pos) * size); } void CHFA::flex_table(ostream &os, const char *name) { const char th_version[] = "notflex"; struct table_set_header th = { 0, 0, 0, 0 }; /** * Change the following two data types to adjust the maximum flex * table size. */ typedef uint16_t state_t; typedef uint32_t trans_t; if (default_base.size() >= (state_t) - 1) { cerr << "Too many states (" << default_base.size() << ") for " "type state_t\n"; exit(1); } if (next_check.size() >= (trans_t) - 1) { cerr << "Too many transitions (" << next_check.size() << ") for " "type trans_t\n"; exit(1); } /** * Create copies of the data structures so that we can dump the tables * using the generic write_flex_table() routine. */ vector equiv_vec; if (eq.size()) { equiv_vec.resize(256); for (map::iterator i = eq.begin(); i != eq.end(); i++) { equiv_vec[i->first] = i->second; } } vector default_vec; vector base_vec; for (DefaultBase::iterator i = default_base.begin(); i != default_base.end(); i++) { default_vec.push_back(num[i->first]); base_vec.push_back(i->second); } vector next_vec; vector check_vec; for (NextCheck::iterator i = next_check.begin(); i != next_check.end(); i++) { next_vec.push_back(num[i->first]); check_vec.push_back(num[i->second]); } /* Write the actual flex parser table. */ size_t hsize = pad64(sizeof(th) + sizeof(th_version) + strlen(name) + 1); th.th_magic = htonl(YYTH_REGEX_MAGIC); th.th_flags = htonl(chfaflags); th.th_hsize = htonl(hsize); th.th_ssize = htonl(hsize + flex_table_size(accept.begin(), accept.end()) + flex_table_size(accept2.begin(), accept2.end()) + (eq.size() ? flex_table_size(equiv_vec.begin(), equiv_vec.end()) : 0) + flex_table_size(base_vec.begin(), base_vec.end()) + flex_table_size(default_vec.begin(), default_vec.end()) + flex_table_size(next_vec.begin(), next_vec.end()) + flex_table_size(check_vec.begin(), check_vec.end())); os.write((char *)&th, sizeof(th)); os << th_version << (char)0 << name << (char)0; os << fill64(sizeof(th) + sizeof(th_version) + strlen(name) + 1); write_flex_table(os, YYTD_ID_ACCEPT, accept.begin(), accept.end()); write_flex_table(os, YYTD_ID_ACCEPT2, accept2.begin(), accept2.end()); if (eq.size()) write_flex_table(os, YYTD_ID_EC, equiv_vec.begin(), equiv_vec.end()); write_flex_table(os, YYTD_ID_BASE, base_vec.begin(), base_vec.end()); write_flex_table(os, YYTD_ID_DEF, default_vec.begin(), default_vec.end()); write_flex_table(os, YYTD_ID_NXT, next_vec.begin(), next_vec.end()); write_flex_table(os, YYTD_ID_CHK, check_vec.begin(), check_vec.end()); } apparmor-2.13.3/parser/libapparmor_re/aare_rules.cc0000644000175000017500000001510413502024172020131 0ustar jjjj/* * (C) 2006, 2007 Andreas Gruenbacher * Copyright (c) 2003-2008 Novell, Inc. (All rights reserved) * Copyright 2009-2013 Canonical Ltd. (All rights reserved) * * The libapparmor library is licensed under the terms of the GNU * Lesser General Public License, version 2.1. Please see the file * COPYING.LGPL. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * * Wrapper around the dfa to convert aa rules into a dfa */ #include #include #include #include #include #include #include #include "aare_rules.h" #include "expr-tree.h" #include "parse.h" #include "hfa.h" #include "chfa.h" #include "../immunix.h" aare_rules::~aare_rules(void) { if (root) root->release(); unique_perms.clear(); expr_map.clear(); } bool aare_rules::add_rule(const char *rule, int deny, uint32_t perms, uint32_t audit, dfaflags_t flags) { return add_rule_vec(deny, perms, audit, 1, &rule, flags); } void aare_rules::add_to_rules(Node *tree, Node *perms) { if (reverse) flip_tree(tree); Node *base = expr_map[perms]; if (base) expr_map[perms] = new AltNode(base, tree); else expr_map[perms] = tree; } static Node *cat_with_null_seperator(Node *l, Node *r) { return new CatNode(new CatNode(l, new CharNode(0)), r); } bool aare_rules::add_rule_vec(int deny, uint32_t perms, uint32_t audit, int count, const char **rulev, dfaflags_t flags) { Node *tree = NULL, *accept; int exact_match; if (regex_parse(&tree, rulev[0])) return false; for (int i = 1; i < count; i++) { Node *subtree = NULL; if (regex_parse(&subtree, rulev[i])) return false; tree = cat_with_null_seperator(tree, subtree); } /* * Check if we have an expression with or without wildcards. This * determines how exec modifiers are merged in accept_perms() based * on how we split permission bitmasks here. */ exact_match = 1; for (depth_first_traversal i(tree); i && exact_match; i++) { if (dynamic_cast(*i) || dynamic_cast(*i) || dynamic_cast(*i) || dynamic_cast(*i) || dynamic_cast(*i)) exact_match = 0; } if (reverse) flip_tree(tree); accept = unique_perms.insert(deny, perms, audit, exact_match); if (flags & DFA_DUMP_RULE_EXPR) { cerr << "rule: "; cerr << rulev[0]; for (int i = 1; i < count; i++) { cerr << "\\x00"; cerr << rulev[i]; } cerr << " -> "; tree->dump(cerr); if (deny) cerr << " deny"; cerr << " (0x" << hex << perms <<"/" << audit << dec << ")"; accept->dump(cerr); cerr << "\n\n"; } add_to_rules(tree, accept); rule_count++; return true; } /* create a dfa from the ruleset * returns: buffer contain dfa tables, @size set to the size of the tables * else NULL on failure, @min_match_len set to the shortest string * that can match the dfa for determining xmatch priority. */ void *aare_rules::create_dfa(size_t *size, int *min_match_len, dfaflags_t flags) { char *buffer = NULL; /* finish constructing the expr tree from the different permission * set nodes */ PermExprMap::iterator i = expr_map.begin(); if (i != expr_map.end()) { if (flags & DFA_CONTROL_TREE_SIMPLE) { Node *tmp = simplify_tree(i->second, flags); root = new CatNode(tmp, i->first); } else root = new CatNode(i->second, i->first); for (i++; i != expr_map.end(); i++) { Node *tmp; if (flags & DFA_CONTROL_TREE_SIMPLE) { tmp = simplify_tree(i->second, flags); } else tmp = i->second; root = new AltNode(root, new CatNode(tmp, i->first)); } } *min_match_len = root->min_match_len(); /* dumping of the none simplified tree without -O no-expr-simplify * is broken because we need to build the tree above first, and * simplification is woven into the build. Reevaluate how to fix * this debug dump. */ label_nodes(root); if (flags & DFA_DUMP_TREE) { cerr << "\nDFA: Expression Tree\n"; root->dump(cerr); cerr << "\n\n"; } if (flags & DFA_CONTROL_TREE_SIMPLE) { /* This is old total tree, simplification point * For now just do simplification up front. It gets most * of the benefit running on the smaller chains, and is * overall faster because there are less nodes. Reevaluate * once tree simplification is rewritten */ //root = simplify_tree(root, flags); if (flags & DFA_DUMP_SIMPLE_TREE) { cerr << "\nDFA: Simplified Expression Tree\n"; root->dump(cerr); cerr << "\n\n"; } } stringstream stream; try { DFA dfa(root, flags); if (flags & DFA_DUMP_UNIQ_PERMS) dfa.dump_uniq_perms("dfa"); if (flags & DFA_CONTROL_MINIMIZE) { dfa.minimize(flags); if (flags & DFA_DUMP_MIN_UNIQ_PERMS) dfa.dump_uniq_perms("minimized dfa"); } if (flags & DFA_CONTROL_FILTER_DENY && flags & DFA_CONTROL_MINIMIZE && dfa.apply_and_clear_deny()) { /* Do a second minimization pass as removal of deny * information has moved some states from accepting * to none accepting partitions * * TODO: add this as a tail pass to minimization * so we don't need to do a full second pass */ dfa.minimize(flags); if (flags & DFA_DUMP_MIN_UNIQ_PERMS) dfa.dump_uniq_perms("minimized dfa"); } if (flags & DFA_CONTROL_REMOVE_UNREACHABLE) dfa.remove_unreachable(flags); if (flags & DFA_DUMP_STATES) dfa.dump(cerr); if (flags & DFA_DUMP_GRAPH) dfa.dump_dot_graph(cerr); map eq; if (flags & DFA_CONTROL_EQUIV) { eq = dfa.equivalence_classes(flags); dfa.apply_equivalence_classes(eq); if (flags & DFA_DUMP_EQUIV) { cerr << "\nDFA equivalence class\n"; dump_equivalence_classes(cerr, eq); } } else if (flags & DFA_DUMP_EQUIV) cerr << "\nDFA did not generate an equivalence class\n"; if (flags & DFA_CONTROL_DIFF_ENCODE) { dfa.diff_encode(flags); if (flags & DFA_DUMP_DIFF_ENCODE) dfa.dump_diff_encode(cerr); } CHFA chfa(dfa, eq, flags); if (flags & DFA_DUMP_TRANS_TABLE) chfa.dump(cerr); chfa.flex_table(stream, ""); } catch(int error) { *size = 0; return NULL; } stringbuf *buf = stream.rdbuf(); buf->pubseekpos(0); *size = buf->in_avail(); buffer = (char *)malloc(*size); if (!buffer) return NULL; buf->sgetn(buffer, *size); return buffer; } apparmor-2.13.3/parser/libapparmor_re/README0000644000175000017500000001037713502024172016367 0ustar jjjjRegular Expression Scanner Generator ==================================== Notes in the scanner File Format -------------------------------- The file format used is based on the GNU flex table file format (--tables-file option; see Table File Format in the flex info pages and the flex sources for documentation). The magic number used in the header is set to 0x1B5E783D insted of 0xF13C57B1 though, which is meant to indicate that the file format logically is not the same: the YY_ID_CHK (check) and YY_ID_DEF (default) tables are used differently. Flex uses state compression to store only the differences between states for states that are similar. The amount of compresion influences the parse speed. The following two states could be stored as in the tables outlined below: States and transitions on specific characters to next states ------------------------------------------------------------ 1: ('a' => 2, 'b' => 3, 'c' => 4) 2: ('a' => 2, 'b' => 3, 'd' => 5) Flex-like table format ---------------------- index: (default, base) 0: ( 0, 0) <== dummy state (nonmatching) 1: ( 0, 0) 2: ( 1, 256) index: (next, check) 0: ( 0, 0) <== unused entry ( 0, 1) <== ord('a') identical entries 0+'a': ( 2, 1) 0+'b': ( 3, 1) 0+'c': ( 4, 1) ( 0, 1) <== (255 - ord('c')) identical entries 256+'c': ( 0, 2) 256+'d': ( 5, 2) Here, state 2 is described as ('c' => 0, 'd' => 5), and everything else as in state 1. The matching algorithm is as follows. Flex-like scanner algorithm --------------------------- /* current state is in , input character */ while (check[base[state] + c] != state) state = default[state]; state = next[state]; /* continue with the next input character */ This state compression algorithm performs well, except when there are many inverted or wildcard matches ("[^x]", "."). Each input character may cause several iterations in the while loop. We will have many inverted character classes ("[^/]") that wouldn't compress very well. Therefore, the regexp matcher uses no state compression, and uses the check and default tables differently. The above states could be stored as follows: Regexp table format ------------------- index: (default, base) 0: ( 0, 0) <== dummy state (nonmatching) 1: ( 0, 0) 2: ( 1, 3) index: (next, check) 0: ( 0, 0) <== unused entry ( 0, 0) <== ord('a') identical, unused entries 0+'a': ( 2, 1) 0+'b': ( 3, 1) 0+'c': ( 4, 1) 3+'a': ( 2, 2) 3+'b': ( 3, 2) 3+'c': ( 0, 0) <== entry is unused 3+'d': ( 5, 2) ( 0, 0) <== (255 - ord('d')) identical, unused entries All the entries with 0 in check (except the first entry, which is deliberately reserved) are still available for other states that fit in there. Regexp scanner algorithm ------------------------ /* current state is in , matching character */ if (check[base[state] + c] == state) state = next[state]; else state = default[state]; /* continue with the next input character */ This representation and algorithm allows states which match more characters than they do not match to be represented as their inverse. For example, a third state that accepts everything other than 'a' can be added to the tables as one entry in (default, base) and one entry in (next, check): State ----- 3: ('a' => 0, everything else => 5) Regexp tables ------------- index: (default, base) 0: ( 0, 0) <== dummy state (nonmatching) 1: ( 0, 0) 2: ( 1, 3) 3: ( 5, 7) index: (next, check) 0: ( 0, 0) <== unused entry ( 0, 0) <== ord('a') identical, unused entries 0+'a': ( 2, 1) 0+'b': ( 3, 1) 0+'c': ( 4, 1) 3+'a': ( 2, 2) 3+'b': ( 3, 2) 3+'c': ( 0, 0) <== entry is unused 3+'d': ( 5, 2) 7+'a': ( 0, 3) ( 0, 0) <== (255 - ord('a')) identical, unused entries While the current code does not implement any form of state compression, the flex state compression representation could be combined by remembering (in a bit per state, for example) which default entries refer to inverted matches, and which refer to parent states. apparmor-2.13.3/parser/libapparmor_re/expr-tree.h0000644000175000017500000005046213502024172017572 0ustar jjjj/* * (C) 2006, 2007 Andreas Gruenbacher * Copyright (c) 2003-2008 Novell, Inc. (All rights reserved) * Copyright 2009-2013 Canonical Ltd. * * The libapparmor library is licensed under the terms of the GNU * Lesser General Public License, version 2.1. Please see the file * COPYING.LGPL. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * * Functions to create/manipulate an expression tree for regular expressions * that have been parsed. * * The expression tree can be used directly after the parse creates it, or * it can be factored so that the set of important nodes is smaller. * Having a reduced set of important nodes generally results in a dfa that * is closer to minimum (fewer redundant states are created). It also * results in fewer important nodes in a the state set during subset * construction resulting in less memory used to create a dfa. * * Generally it is worth doing expression tree simplification before dfa * construction, if the regular expression tree contains any alternations. * Even if the regular expression doesn't simplification should be fast * enough that it can be used with minimal overhead. */ #ifndef __LIBAA_RE_EXPR_H #define __LIBAA_RE_EXPR_H #include #include #include #include #include #include "apparmor_re.h" using namespace std; typedef unsigned char uchar; typedef set Chars; ostream &operator<<(ostream &os, uchar c); /* Compute the union of two sets. */ template set operator+(const set &a, const set &b) { set c(a); c.insert(b.begin(), b.end()); return c; } /** * When creating DFAs from regex trees, a DFA state is constructed from * a set of important nodes in the syntax tree. This includes AcceptNodes, * which indicate that when a match ends in a particular state, the * regular expressions that the AcceptNode belongs to match. */ class Node; class ImportantNode; typedef set NodeSet; /** * Text-dump a state (for debugging). */ ostream &operator<<(ostream &os, const NodeSet &state); /** * Out-edges from a state to another: we store the follow-set of Nodes * for each input character that is not a default match in * cases (i.e., following a CharNode or CharSetNode), and default * matches in otherwise as well as in all matching explicit cases * (i.e., following an AnyCharNode or NotCharSetNode). This avoids * enumerating all the explicit tranitions for default matches. */ typedef struct Cases { typedef map::iterator iterator; iterator begin() { return cases.begin(); } iterator end() { return cases.end(); } Cases(): otherwise(0) { } map cases; NodeSet *otherwise; } Cases; ostream &operator<<(ostream &os, Node &node); /* An abstract node in the syntax tree. */ class Node { public: Node(): nullable(false), label(0) { child[0] = child[1] = 0; } Node(Node *left): nullable(false), label(0) { child[0] = left; child[1] = 0; } Node(Node *left, Node *right): nullable(false), label(0) { child[0] = left; child[1] = right; } virtual ~Node() { if (child[0]) child[0]->release(); if (child[1]) child[1]->release(); } /** * See the "Dragon Book" for an explanation of nullable, firstpos, * lastpos, and followpos. */ virtual void compute_nullable() { } virtual void compute_firstpos() = 0; virtual void compute_lastpos() = 0; virtual void compute_followpos() { } /* * min_match_len determines the smallest string that can match the * syntax tree. This is used to determine the priority of a regex. */ virtual int min_match_len() { return 0; } /* * contains_null returns if the expression tree contains a null character. * Null characters indicate that the rest of the DFA matches the xattrs and * not the path. This is used to compute min_match_len. */ virtual bool contains_null() { return false; } virtual int eq(Node *other) = 0; virtual ostream &dump(ostream &os) = 0; void dump_syntax_tree(ostream &os); virtual void normalize(int dir) { if (child[dir]) child[dir]->normalize(dir); if (child[!dir]) child[!dir]->normalize(dir); } /* return false if no work done */ virtual int normalize_eps(int dir __attribute__((unused))) { return 0; } bool nullable; NodeSet firstpos, lastpos, followpos; /* child 0 is left, child 1 is right */ Node *child[2]; unsigned int label; /* unique number for debug etc */ /** * We indirectly release Nodes through a virtual function because * accept and Eps Nodes are shared, and must be treated specially. * We could use full reference counting here but the indirect release * is sufficient and has less overhead */ virtual void release(void) { delete this; } }; class InnerNode: public Node { public: InnerNode(): Node() { }; InnerNode(Node *left): Node(left) { }; InnerNode(Node *left, Node *right): Node(left, right) { }; }; class OneChildNode: public InnerNode { public: OneChildNode(Node *left): InnerNode(left) { }; }; class TwoChildNode: public InnerNode { public: TwoChildNode(Node *left, Node *right): InnerNode(left, right) { }; virtual int normalize_eps(int dir); }; class LeafNode: public Node { public: LeafNode(): Node() { }; virtual void normalize(int dir __attribute__((unused))) { return; } }; /* Match nothing (//). */ class EpsNode: public LeafNode { public: EpsNode(): LeafNode() { nullable = true; label = 0; } void release(void) { /* don't delete Eps nodes because there is a single static * instance shared by all trees. Look for epsnode in the code */ } void compute_firstpos() { } void compute_lastpos() { } int eq(Node *other) { if (dynamic_cast(other)) return 1; return 0; } ostream &dump(ostream &os) { return os << "[]"; } }; /** * Leaf nodes in the syntax tree are important to us: they describe the * characters that the regular expression matches. We also consider * AcceptNodes import: they indicate when a regular expression matches. */ class ImportantNode: public LeafNode { public: ImportantNode(): LeafNode() { } void compute_firstpos() { firstpos.insert(this); } void compute_lastpos() { lastpos.insert(this); } virtual void follow(Cases &cases) = 0; virtual int is_accept(void) = 0; virtual int is_postprocess(void) = 0; }; /* common base class for all the different classes that contain * character information. */ class CNode: public ImportantNode { public: CNode(): ImportantNode() { } int is_accept(void) { return false; } int is_postprocess(void) { return false; } }; /* Match one specific character (/c/). */ class CharNode: public CNode { public: CharNode(uchar c): c(c) { } void follow(Cases &cases) { NodeSet **x = &cases.cases[c]; if (!*x) { if (cases.otherwise) *x = new NodeSet(*cases.otherwise); else *x = new NodeSet; } (*x)->insert(followpos.begin(), followpos.end()); } int eq(Node *other) { CharNode *o = dynamic_cast(other); if (o) { return c == o->c; } return 0; } ostream &dump(ostream &os) { return os << c; } int min_match_len() { if (c == 0) { // Null character indicates end of string. return 0; } return 1; } bool contains_null() { return c == 0; } uchar c; }; /* Match a set of characters (/[abc]/). */ class CharSetNode: public CNode { public: CharSetNode(Chars &chars): chars(chars) { } void follow(Cases &cases) { for (Chars::iterator i = chars.begin(); i != chars.end(); i++) { NodeSet **x = &cases.cases[*i]; if (!*x) { if (cases.otherwise) *x = new NodeSet(*cases.otherwise); else *x = new NodeSet; } (*x)->insert(followpos.begin(), followpos.end()); } } int eq(Node *other) { CharSetNode *o = dynamic_cast(other); if (!o || chars.size() != o->chars.size()) return 0; for (Chars::iterator i = chars.begin(), j = o->chars.begin(); i != chars.end() && j != o->chars.end(); i++, j++) { if (*i != *j) return 0; } return 1; } ostream &dump(ostream &os) { os << '['; for (Chars::iterator i = chars.begin(); i != chars.end(); i++) os << *i; return os << ']'; } int min_match_len() { if (contains_null()) { return 0; } return 1; } bool contains_null() { for (Chars::iterator i = chars.begin(); i != chars.end(); i++) { if (*i == 0) { return true; } } return false; } Chars chars; }; /* Match all except one character (/[^abc]/). */ class NotCharSetNode: public CNode { public: NotCharSetNode(Chars &chars): chars(chars) { } void follow(Cases &cases) { if (!cases.otherwise) cases.otherwise = new NodeSet; for (Chars::iterator j = chars.begin(); j != chars.end(); j++) { NodeSet **x = &cases.cases[*j]; if (!*x) *x = new NodeSet(*cases.otherwise); } /* Note: Add to the nonmatching characters after copying away * the old otherwise state for the matching characters. */ cases.otherwise->insert(followpos.begin(), followpos.end()); for (Cases::iterator i = cases.begin(); i != cases.end(); i++) { if (chars.find(i->first) == chars.end()) i->second->insert(followpos.begin(), followpos.end()); } } int eq(Node *other) { NotCharSetNode *o = dynamic_cast(other); if (!o || chars.size() != o->chars.size()) return 0; for (Chars::iterator i = chars.begin(), j = o->chars.begin(); i != chars.end() && j != o->chars.end(); i++, j++) { if (*i != *j) return 0; } return 1; } ostream &dump(ostream &os) { os << "[^"; for (Chars::iterator i = chars.begin(); i != chars.end(); i++) os << *i; return os << ']'; } int min_match_len() { if (contains_null()) { return 0; } return 1; } bool contains_null() { for (Chars::iterator i = chars.begin(); i != chars.end(); i++) { if (*i == 0) { return false; } } return true; } Chars chars; }; /* Match any character (/./). */ class AnyCharNode: public CNode { public: AnyCharNode() { } void follow(Cases &cases) { if (!cases.otherwise) cases.otherwise = new NodeSet; cases.otherwise->insert(followpos.begin(), followpos.end()); for (Cases::iterator i = cases.begin(); i != cases.end(); i++) i->second->insert(followpos.begin(), followpos.end()); } int eq(Node *other) { if (dynamic_cast(other)) return 1; return 0; } ostream &dump(ostream &os) { return os << "."; } bool contains_null() { return true; } }; /* Match a node zero or more times. (This is a unary operator.) */ class StarNode: public OneChildNode { public: StarNode(Node *left): OneChildNode(left) { nullable = true; } void compute_firstpos() { firstpos = child[0]->firstpos; } void compute_lastpos() { lastpos = child[0]->lastpos; } void compute_followpos() { NodeSet from = child[0]->lastpos, to = child[0]->firstpos; for (NodeSet::iterator i = from.begin(); i != from.end(); i++) { (*i)->followpos.insert(to.begin(), to.end()); } } int eq(Node *other) { if (dynamic_cast(other)) return child[0]->eq(other->child[0]); return 0; } ostream &dump(ostream &os) { os << '('; child[0]->dump(os); return os << ")*"; } bool contains_null() { return child[0]->contains_null(); } }; /* Match a node one or more times. (This is a unary operator.) */ class PlusNode: public OneChildNode { public: PlusNode(Node *left): OneChildNode(left) { } void compute_nullable() { nullable = child[0]->nullable; } void compute_firstpos() { firstpos = child[0]->firstpos; } void compute_lastpos() { lastpos = child[0]->lastpos; } void compute_followpos() { NodeSet from = child[0]->lastpos, to = child[0]->firstpos; for (NodeSet::iterator i = from.begin(); i != from.end(); i++) { (*i)->followpos.insert(to.begin(), to.end()); } } int eq(Node *other) { if (dynamic_cast(other)) return child[0]->eq(other->child[0]); return 0; } ostream &dump(ostream &os) { os << '('; child[0]->dump(os); return os << ")+"; } int min_match_len() { return child[0]->min_match_len(); } bool contains_null() { return child[0]->contains_null(); } }; /* Match a pair of consecutive nodes. */ class CatNode: public TwoChildNode { public: CatNode(Node *left, Node *right): TwoChildNode(left, right) { } void compute_nullable() { nullable = child[0]->nullable && child[1]->nullable; } void compute_firstpos() { if (child[0]->nullable) firstpos = child[0]->firstpos + child[1]->firstpos; else firstpos = child[0]->firstpos; } void compute_lastpos() { if (child[1]->nullable) lastpos = child[0]->lastpos + child[1]->lastpos; else lastpos = child[1]->lastpos; } void compute_followpos() { NodeSet from = child[0]->lastpos, to = child[1]->firstpos; for (NodeSet::iterator i = from.begin(); i != from.end(); i++) { (*i)->followpos.insert(to.begin(), to.end()); } } int eq(Node *other) { if (dynamic_cast(other)) { if (!child[0]->eq(other->child[0])) return 0; return child[1]->eq(other->child[1]); } return 0; } ostream &dump(ostream &os) { child[0]->dump(os); child[1]->dump(os); return os; } void normalize(int dir); int min_match_len() { int len = child[0]->min_match_len(); if (child[0]->contains_null()) { // Null characters are used to indicate when the DFA transitions // from matching the path to matching the xattrs. If the left child // contains a null character, the right side doesn't contribute to // the path match. return len; } return len + child[1]->min_match_len(); } bool contains_null() { return child[0]->contains_null() || child[1]->contains_null(); } }; /* Match one of two alternative nodes. */ class AltNode: public TwoChildNode { public: AltNode(Node *left, Node *right): TwoChildNode(left, right) { } void compute_nullable() { nullable = child[0]->nullable || child[1]->nullable; } void compute_lastpos() { lastpos = child[0]->lastpos + child[1]->lastpos; } void compute_firstpos() { firstpos = child[0]->firstpos + child[1]->firstpos; } int eq(Node *other) { if (dynamic_cast(other)) { if (!child[0]->eq(other->child[0])) return 0; return child[1]->eq(other->child[1]); } return 0; } ostream &dump(ostream &os) { os << '('; child[0]->dump(os); os << '|'; child[1]->dump(os); os << ')'; return os; } void normalize(int dir); int min_match_len() { int m1, m2; m1 = child[0]->min_match_len(); m2 = child[1]->min_match_len(); if (m1 < m2) { return m1; } return m2; } bool contains_null() { return child[0]->contains_null() || child[1]->contains_null(); } }; class SharedNode: public ImportantNode { public: SharedNode() { } void release(void) { /* don't delete SharedNodes via release as they are shared, and * will be deleted when the table they are stored in is deleted */ } void follow(Cases &cases __attribute__ ((unused))) { /* Nothing to follow. */ } /* requires shared nodes to be common by pointer */ int eq(Node *other) { return (this == other); } }; /** * Indicate that a regular expression matches. An AcceptNode itself * doesn't match anything, so it will never generate any transitions. */ class AcceptNode: public SharedNode { public: AcceptNode() { } int is_accept(void) { return true; } int is_postprocess(void) { return false; } }; class MatchFlag: public AcceptNode { public: MatchFlag(uint32_t flag, uint32_t audit): flag(flag), audit(audit) { } ostream &dump(ostream &os) { return os << "< 0x" << hex << flag << '>'; } uint32_t flag; uint32_t audit; }; class ExactMatchFlag: public MatchFlag { public: ExactMatchFlag(uint32_t flag, uint32_t audit): MatchFlag(flag, audit) {} }; class DenyMatchFlag: public MatchFlag { public: DenyMatchFlag(uint32_t flag, uint32_t quiet): MatchFlag(flag, quiet) {} }; /* Traverse the syntax tree depth-first in an iterator-like manner. */ class depth_first_traversal { stackpos; void push_left(Node *node) { pos.push(node); while (dynamic_cast(node)) { pos.push(node->child[0]); node = node->child[0]; } } public: depth_first_traversal(Node *node) { push_left(node); } Node *operator*() { return pos.top(); } Node *operator->() { return pos.top(); } operator bool() { return !pos.empty(); } void operator++(int) { Node *last = pos.top(); pos.pop(); if (!pos.empty()) { /* no need to dynamic cast, as we just popped a node so * the top node must be an inner node */ InnerNode *node = (InnerNode *) (pos.top()); if (node->child[1] && node->child[1] != last) { push_left(node->child[1]); } } } }; struct node_counts { int charnode; int charset; int notcharset; int alt; int plus; int star; int any; int cat; }; extern EpsNode epsnode; int debug_tree(Node *t); Node *simplify_tree(Node *t, dfaflags_t flags); void label_nodes(Node *root); unsigned long hash_NodeSet(NodeSet *ns); void flip_tree(Node *node); /* * hashedNodes - for efficient set comparison */ class hashedNodeSet { public: unsigned long hash; NodeSet *nodes; hashedNodeSet(NodeSet *n): nodes(n) { hash = hash_NodeSet(n); } bool operator<(hashedNodeSet const &rhs)const { if (hash == rhs.hash) { if (nodes->size() == rhs.nodes->size()) return *nodes < *(rhs.nodes); else return nodes->size() < rhs.nodes->size(); } else { return hash < rhs.hash; } } }; class hashedNodeVec { public: typedef ImportantNode ** iterator; iterator begin() { return nodes; } iterator end() { iterator t = nodes ? &nodes[len] : NULL; return t; } unsigned long hash; unsigned long len; ImportantNode **nodes; hashedNodeVec(NodeSet *n) { hash = hash_NodeSet(n); len = n->size(); nodes = new ImportantNode *[n->size()]; unsigned int j = 0; for (NodeSet::iterator i = n->begin(); i != n->end(); i++, j++) { nodes[j] = *i; } } hashedNodeVec(NodeSet *n, unsigned long h): hash(h) { len = n->size(); nodes = new ImportantNode *[n->size()]; ImportantNode **j = nodes; for (NodeSet::iterator i = n->begin(); i != n->end(); i++) { *(j++) = *i; } } ~hashedNodeVec() { delete [] nodes; } unsigned long size()const { return len; } bool operator<(hashedNodeVec const &rhs)const { if (hash == rhs.hash) { if (len == rhs.size()) { for (unsigned int i = 0; i < len; i++) { if (nodes[i] != rhs.nodes[i]) return nodes[i] < rhs.nodes[i]; } return false; } return len < rhs.size(); } return hash < rhs.hash; } }; class CacheStats { public: unsigned long dup, sum, max; CacheStats(void): dup(0), sum(0), max(0) { }; void clear(void) { dup = sum = max = 0; } virtual unsigned long size(void) const = 0; }; class NodeCache: public CacheStats { public: set cache; NodeCache(void): cache() { }; ~NodeCache() { clear(); }; virtual unsigned long size(void) const { return cache.size(); } void clear() { for (set::iterator i = cache.begin(); i != cache.end(); i++) { delete i->nodes; } cache.clear(); CacheStats::clear(); } NodeSet *insert(NodeSet *nodes) { if (!nodes) return NULL; pair::iterator,bool> uniq; uniq = cache.insert(hashedNodeSet(nodes)); if (uniq.second == false) { delete(nodes); dup++; } else { sum += nodes->size(); if (nodes->size() > max) max = nodes->size(); } return uniq.first->nodes; } }; struct deref_less_than { bool operator()(hashedNodeVec * const &lhs, hashedNodeVec * const &rhs)const { return *lhs < *rhs; } }; class NodeVecCache: public CacheStats { public: set cache; NodeVecCache(void): cache() { }; ~NodeVecCache() { clear(); }; virtual unsigned long size(void) const { return cache.size(); } void clear() { for (set::iterator i = cache.begin(); i != cache.end(); i++) { delete *i; } cache.clear(); CacheStats::clear(); } hashedNodeVec *insert(NodeSet *nodes) { if (!nodes) return NULL; pair::iterator,bool> uniq; hashedNodeVec *nv = new hashedNodeVec(nodes); uniq = cache.insert(nv); if (uniq.second == false) { delete nv; dup++; } else { sum += nodes->size(); if (nodes->size() > max) max = nodes->size(); } delete(nodes); return (*uniq.first); } }; #endif /* __LIBAA_RE_EXPR */ apparmor-2.13.3/parser/libapparmor_re/Makefile0000644000175000017500000000152113502024172017136 0ustar jjjj# Profiling: #EXTRA_CFLAGS = -pg ifdef USE_SYSTEM # Using the system libapparmor INCLUDE_APPARMOR = else INCLUDE_APPARMOR = -I../../libraries/libapparmor/include endif TARGET=libapparmor_re.a CFLAGS ?= -g -Wall -O2 ${EXTRA_CFLAGS} -std=gnu++0x CXXFLAGS := ${CFLAGS} ${INCLUDE_APPARMOR} ARFLAGS=-rcs BISON := bison all : ${TARGET} UNITTESTS = tst_parse libapparmor_re.a: parse.o expr-tree.o hfa.o chfa.o aare_rules.o ar ${ARFLAGS} $@ $^ expr-tree.o: expr-tree.cc expr-tree.h hfa.o: hfa.cc apparmor_re.h hfa.h ../immunix.h aare_rules.o: aare_rules.cc aare_rules.h apparmor_re.h expr-tree.h hfa.h chfa.h parse.h ../immunix.h chfa.o: chfa.cc chfa.h ../immunix.h parse.o : parse.cc apparmor_re.h expr-tree.h parse.cc : parse.y parse.h flex-tables.h ../immunix.h ${BISON} -o $@ $< clean: rm -f *.o parse.cc ${TARGET} *.gcda *.gcno apparmor-2.13.3/parser/libapparmor_re/hfa.cc0000644000175000017500000011207513502024172016552 0ustar jjjj/* * (C) 2006, 2007 Andreas Gruenbacher * Copyright (c) 2003-2008 Novell, Inc. (All rights reserved) * Copyright 2009-2012 Canonical Ltd. * * The libapparmor library is licensed under the terms of the GNU * Lesser General Public License, version 2.1. Please see the file * COPYING.LGPL. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * * Base of implementation based on the Lexical Analysis chapter of: * Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman: * Compilers: Principles, Techniques, and Tools (The "Dragon Book"), * Addison-Wesley, 1986. */ #include #include #include #include #include #include #include #include #include #include "expr-tree.h" #include "hfa.h" #include "../immunix.h" ostream &operator<<(ostream &os, const CacheStats &cache) { /* dump the state label */ os << "cache: size="; os << cache.size(); os << " dups="; os << cache.dup; os << " longest="; os << cache.max; if (cache.size()) { os << " avg="; os << cache.sum / cache.size(); } return os; } ostream &operator<<(ostream &os, const ProtoState &proto) { /* dump the state label */ os << '{'; os << proto.nnodes; os << ','; os << proto.anodes; os << '}'; return os; } ostream &operator<<(ostream &os, const State &state) { /* dump the state label */ os << '{'; os << state.label; os << '}'; return os; } /** * diff_weight - Find differential compression distance between @rel and @this * @rel: State to compare too * Returns: An integer indicating how good rel is as a base, larger == better * * Find the relative weighted difference for differential state compression * with queried state being compressed against @rel * * +1 for each transition that matches (char and dest - saves a transition) * 0 for each transition that doesn't match and exists in both states * 0 for transition that self has and @other doesn't (no extra required) * -1 for each transition that is in @rel and not in @this (have to override) * * @rel should not be a state that has already been made differential or it may * introduce extra transitions as it does not recurse to find all transitions * * Should be applied after state minimization */ int State::diff_weight(State *rel) { int weight = 0; if (this == rel) return 0; if (rel->diff->rel) { /* Can only be diff encoded against states that are relative * to a state of a lower depth. ie, at most one sibling in * the chain */ if (rel->diff->rel->diff->depth >= this->diff->depth) return 0; } else if (rel->diff->depth >= this->diff->depth) return 0; if (rel->flags & DiffEncodeFlag) { for (int i = 0; i < 256; i++) { State *state = rel->next(i); StateTrans::iterator j = trans.find(i); if (j != trans.end()) { if (state == j->second) weight++; /* else 0 - keep transition to mask */ } else if (state == otherwise) { /* 0 - match of default against @rel * We don't save a transition but don't have * to mask either */ } else { /* @rel has transition not covered by @this. * Need to add a transition to mask it */ weight--; } } return weight; } unsigned int count = 0; for (StateTrans::iterator i = rel->trans.begin(); i != rel->trans.end(); i++) { StateTrans::iterator j = trans.find(i->first); if (j != trans.end()) { if (i->second == j->second) weight++; /* } else { 0 - keep transition to mask */ count++; } else if (i->second == otherwise) { /* 0 - match of default against @rel * We don't save a transition but don't have to * mask either */ } else { /* rel has transition not covered by @this. Need to * add a transition to mask */ weight--; } } /* cover transitions in @this but not in @rel */ unsigned int this_count = 0; if (count < trans.size()) { for (StateTrans::iterator i = trans.begin(); i != trans.end(); i++) { StateTrans::iterator j = rel->trans.find(i->first); if (j == rel->trans.end()) { this_count++; if (i->second == rel->otherwise) /* replaced by rel->cases.otherwise */ weight++; } } } if (rel->otherwise != otherwise) { /* rel default transitions have to be masked with transitions * This covers all transitions not covered above */ weight -= 256 - (rel->trans.size() + this_count); } return weight; } /** * make_relative - Make this state relative to @rel * @rel: state to make this state relative too * * @rel can be a relative (differentially compressed state) */ int State::make_relative(State *rel) { int weight = 0; if (this == rel || !rel) return 0; if (flags & DiffEncodeFlag) return 0; flags |= DiffEncodeFlag; for (int i = 0; i < 256 ; i++) { State *next = rel->next(i); StateTrans::iterator j = trans.find(i); if (j != trans.end()) { if (j->second == next) { trans.erase(j); weight++; } /* else keep transition to mask */ } else if (otherwise == next) { /* do nothing, otherwise transition disappears when * reassigned */ } else { /* need a new transition to mask those in lower state */ trans[i] = otherwise; weight--; } } otherwise = rel; return weight; } /** * flatten_differential - remove differential encode from this state */ void State::flatten_relative(void) { if (!(flags & DiffEncodeFlag)) return; map count; for (int i = 0; i < 256; i++) count[next(i)] += 1; int j = 0; State *def = next(0); for (int i = 1; i < 256; i++) { if (count[next(i)] > count[next(j)]) { j = i; def = next(i); } } for (int i = 0; i < 256; i++) { if (trans.find(i) != trans.end()) { if (trans[i] == def) trans.erase(i); } else { if (trans[i] != def) trans[i] = next(i); } } otherwise = def; flags = flags & ~DiffEncodeFlag; } static void split_node_types(NodeSet *nodes, NodeSet **anodes, NodeSet **nnodes ) { *anodes = *nnodes = NULL; for (NodeSet::iterator i = nodes->begin(); i != nodes->end(); ) { if ((*i)->is_accept()) { if (!*anodes) *anodes = new NodeSet; (*anodes)->insert(*i); NodeSet::iterator k = i++; nodes->erase(k); } else i++; } *nnodes = nodes; } State *DFA::add_new_state(NodeSet *anodes, NodeSet *nnodes, State *other) { hashedNodeVec *nnodev; nnodev = nnodes_cache.insert(nnodes); anodes = anodes_cache.insert(anodes); ProtoState proto; proto.init(nnodev, anodes); State *state = new State(node_map.size(), proto, other); pair x = node_map.insert(proto, state); if (x.second == false) { delete state; } else { states.push_back(state); work_queue.push_back(state); } return x.first->second; } State *DFA::add_new_state(NodeSet *nodes, State *other) { /* The splitting of nodes should probably get pushed down into * follow(), ie. put in separate lists from the start */ NodeSet *anodes, *nnodes; split_node_types(nodes, &anodes, &nnodes); State *state = add_new_state(anodes, nnodes, other); return state; } void DFA::update_state_transitions(State *state) { /* Compute possible transitions for state->nodes. This is done by * iterating over all the nodes in state->nodes and combining the * transitions. * * The resultant transition set is a mapping of characters to * sets of nodes. * * Note: the follow set for accept nodes is always empty so we don't * need to compute follow for the accept nodes in a protostate */ Cases cases; for (hashedNodeVec::iterator i = state->proto.nnodes->begin(); i != state->proto.nnodes->end(); i++) (*i)->follow(cases); /* Now for each set of nodes in the computed transitions, make * sure that there is a state that maps to it, and add the * matching case to the state. */ /* check the default transition first */ if (cases.otherwise) state->otherwise = add_new_state(cases.otherwise, nonmatching); else state->otherwise = nonmatching; /* For each transition from *from, check if the set of nodes it * transitions to already has been mapped to a state */ for (Cases::iterator j = cases.begin(); j != cases.end(); j++) { State *target; target = add_new_state(j->second, nonmatching); /* Don't insert transition that the otherwise transition * already covers */ if (target != state->otherwise) state->trans[j->first] = target; } } /* WARNING: This routine can only be called from within DFA creation as * the nodes value is only valid during dfa construction. */ void DFA::dump_node_to_dfa(void) { cerr << "Mapping of States to expr nodes\n" " State <= Nodes\n" "-------------------\n"; for (Partition::iterator i = states.begin(); i != states.end(); i++) cerr << " " << (*i)->label << " <= " << (*i)->proto << "\n"; } void DFA::process_work_queue(const char *header, dfaflags_t flags) { int i = 0; while (!work_queue.empty()) { if (i % 1000 == 0 && (flags & DFA_DUMP_PROGRESS)) { cerr << "\033[2K" << header << ": queue " << work_queue.size() << "\tstates " << states.size() << "\teliminated duplicates " << node_map.dup << "\r"; } i++; State *from = work_queue.front(); work_queue.pop_front(); /* Update 'from's transitions, and if it transitions to any * unknown State create it and add it to the work_queue */ update_state_transitions(from); } /* while (!work_queue.empty()) */ } /** * Construct a DFA from a syntax tree. */ DFA::DFA(Node *root, dfaflags_t flags): root(root) { diffcount = 0; /* set by diff_encode */ if (flags & DFA_DUMP_PROGRESS) fprintf(stderr, "Creating dfa:\r"); for (depth_first_traversal i(root); i; i++) { (*i)->compute_nullable(); (*i)->compute_firstpos(); (*i)->compute_lastpos(); } if (flags & DFA_DUMP_PROGRESS) fprintf(stderr, "Creating dfa: followpos\r"); for (depth_first_traversal i(root); i; i++) { (*i)->compute_followpos(); } nonmatching = add_new_state(new NodeSet, NULL); start = add_new_state(new NodeSet(root->firstpos), nonmatching); /* the work_queue contains the states that need to have their * transitions computed. This could be done with a recursive * algorithm instead of a work_queue, but it would be slightly slower * and consume more memory. * * TODO: currently the work_queue is treated in a breadth first * search manner. Test using the work_queue in a depth first * manner, this may help reduce the number of entries on the * work_queue at any given time, thus reducing peak memory use. */ work_queue.push_back(start); process_work_queue("Creating dfa", flags); /* cleanup Sets of nodes used computing the DFA as they are no longer * needed. */ for (depth_first_traversal i(root); i; i++) { (*i)->firstpos.clear(); (*i)->lastpos.clear(); (*i)->followpos.clear(); } if (flags & DFA_DUMP_NODE_TO_DFA) dump_node_to_dfa(); if (flags & (DFA_DUMP_STATS)) { cerr << "\033[2KCreated dfa: states " << states.size() << " proto { " << node_map << " }, nnodes { " << nnodes_cache << " }, anodes { " << anodes_cache << " }\n"; } /* Clear out uniq_nnodes as they are no longer needed. * Do not clear out uniq_anodes, as we need them for minimizations * diffs, unions, ... */ nnodes_cache.clear(); node_map.clear(); } DFA::~DFA() { anodes_cache.clear(); nnodes_cache.clear(); for (Partition::iterator i = states.begin(); i != states.end(); i++) delete *i; } State *DFA::match_len(State *state, const char *str, size_t len) { for (; len > 0; ++str, --len) state = state->next(*str); return state; } State *DFA::match_until(State *state, const char *str, const char term) { while (*str != term) state = state->next(*str++); return state; } State *DFA::match(const char *str) { return match_until(start, str, 0); } void DFA::dump_uniq_perms(const char *s) { set uniq; for (Partition::iterator i = states.begin(); i != states.end(); i++) uniq.insert((*i)->perms); cerr << "Unique Permission sets: " << s << " (" << uniq.size() << ")\n"; cerr << "----------------------\n"; for (set::iterator i = uniq.begin(); i != uniq.end(); i++) { cerr << " allow:" << hex << i->allow << " deny:" << i->deny << " audit:" << i->audit << " quiet:" << i->quiet << dec << "\n"; } } /* Remove dead or unreachable states */ void DFA::remove_unreachable(dfaflags_t flags) { set reachable; /* find the set of reachable states */ reachable.insert(nonmatching); work_queue.push_back(start); while (!work_queue.empty()) { State *from = work_queue.front(); work_queue.pop_front(); reachable.insert(from); if (from->otherwise != nonmatching && reachable.find(from->otherwise) == reachable.end()) work_queue.push_back(from->otherwise); for (StateTrans::iterator j = from->trans.begin(); j != from->trans.end(); j++) { if (reachable.find(j->second) == reachable.end()) work_queue.push_back(j->second); } } /* walk the set of states and remove any that aren't reachable */ if (reachable.size() < states.size()) { int count = 0; Partition::iterator i; Partition::iterator next; for (i = states.begin(); i != states.end(); i = next) { next = i; next++; if (reachable.find(*i) == reachable.end()) { if (flags & DFA_DUMP_UNREACHABLE) { cerr << "unreachable: " << **i; if (*i == start) cerr << " <=="; if ((*i)->perms.is_accept()) (*i)->perms.dump(cerr); cerr << "\n"; } State *current = *i; states.erase(i); delete(current); count++; } } if (count && (flags & DFA_DUMP_STATS)) cerr << "DFA: states " << states.size() << " removed " << count << " unreachable states\n"; } } /* test if two states have the same transitions under partition_map */ bool DFA::same_mappings(State *s1, State *s2) { /* assumes otherwise is set to best choice, if there are multiple * otherwise choices this will fail to fully minimize the dfa * if we are not careful. Make sure in cases with multiple * equiv otherwise we always choose the same otherwise to avoid */ if (s1->otherwise->partition != s2->otherwise->partition) return false; StateTrans::iterator j1; StateTrans::iterator j2; for (j1 = s1->trans.begin(), j2 = s2->trans.begin(); j1 != s1->trans.end() && j2 != s2->trans.end(); /*inc inline*/) { if (j1->first < j2->first) { if (j1->second->partition != s2->otherwise->partition) return false; j1++; } else if (j1->first == j2->first) { if (j1->second->partition != j2->second->partition) return false; j1++; j2++; } else { if (s1->otherwise->partition != j2->second->partition) return false; j2++; } } for ( ; j1 != s1->trans.end(); j1++) { if (j1->second->partition != s2->otherwise->partition) return false; } for ( ; j2 != s2->trans.end(); j2++) { if (j2->second->partition != s1->otherwise->partition) return false; } return true; } int DFA::apply_and_clear_deny(void) { int c = 0; for (Partition::iterator i = states.begin(); i != states.end(); i++) c += (*i)->apply_and_clear_deny(); return c; } /* minimize the number of dfa states */ void DFA::minimize(dfaflags_t flags) { map, Partition *> perm_map; list partitions; /* Set up the initial partitions * minimium of - 1 non accepting, and 1 accepting * if trans hashing is used the accepting and non-accepting partitions * can be further split based on the number and type of transitions * a state makes. * If permission hashing is enabled the accepting partitions can * be further divided by permissions. This can result in not * obtaining a truely minimized dfa but comes close, and can speedup * minimization. */ int accept_count = 0; int final_accept = 0; for (Partition::iterator i = states.begin(); i != states.end(); i++) { size_t hash = 0; uint64_t permtype = ((uint64_t) (PACK_AUDIT_CTL((*i)->perms.audit, (*i)->perms.quiet & (*i)->perms.deny)) << 32) | (uint64_t) (*i)->perms.allow; pair group = make_pair(permtype, hash); map, Partition *>::iterator p = perm_map.find(group); if (p == perm_map.end()) { Partition *part = new Partition(); part->push_back(*i); perm_map.insert(make_pair(group, part)); partitions.push_back(part); (*i)->partition = part; if (permtype) accept_count++; } else { (*i)->partition = p->second; p->second->push_back(*i); } if ((flags & DFA_DUMP_PROGRESS) && (partitions.size() % 1000 == 0)) cerr << "\033[2KMinimize dfa: partitions " << partitions.size() << "\tinit " << partitions.size() << " (accept " << accept_count << ")\r"; } /* perm_map is no longer needed so free the memory it is using. * Don't remove - doing it manually here helps reduce peak memory usage. */ perm_map.clear(); int init_count = partitions.size(); if (flags & DFA_DUMP_PROGRESS) cerr << "\033[2KMinimize dfa: partitions " << partitions.size() << "\tinit " << init_count << " (accept " << accept_count << ")\r"; /* Now do repartitioning until each partition contains the set of * states that are the same. This will happen when the partition * splitting stables. With a worse case of 1 state per partition * ie. already minimized. */ Partition *new_part; int new_part_count; do { new_part_count = 0; for (list::iterator p = partitions.begin(); p != partitions.end(); p++) { new_part = NULL; State *rep = *((*p)->begin()); Partition::iterator next; for (Partition::iterator s = ++(*p)->begin(); s != (*p)->end();) { if (same_mappings(rep, *s)) { ++s; continue; } if (!new_part) { new_part = new Partition; list::iterator tmp = p; partitions.insert(++tmp, new_part); new_part_count++; } new_part->push_back(*s); s = (*p)->erase(s); } /* remapping partition_map for new_part entries * Do not do this above as it messes up same_mappings */ if (new_part) { for (Partition::iterator m = new_part->begin(); m != new_part->end(); m++) { (*m)->partition = new_part; } } if ((flags & DFA_DUMP_PROGRESS) && (partitions.size() % 100 == 0)) cerr << "\033[2KMinimize dfa: partitions " << partitions.size() << "\tinit " << init_count << " (accept " << accept_count << ")\r"; } } while (new_part_count); if (partitions.size() == states.size()) { if (flags & DFA_DUMP_STATS) cerr << "\033[2KDfa minimization no states removed: partitions " << partitions.size() << "\tinit " << init_count << " (accept " << accept_count << ")\n"; goto out; } /* Remap the dfa so it uses the representative states * Use the first state of a partition as the representative state * At this point all states with in a partion have transitions * to states within the same partitions, however this can slow * down compressed dfa compression as there are more states, */ if (flags & DFA_DUMP_MIN_PARTS) cerr << "Partitions after minimization\n"; for (list::iterator p = partitions.begin(); p != partitions.end(); p++) { /* representative state for this partition */ State *rep = *((*p)->begin()); if (flags & DFA_DUMP_MIN_PARTS) cerr << *rep << " : "; /* update representative state's transitions */ rep->otherwise = *rep->otherwise->partition->begin(); for (StateTrans::iterator c = rep->trans.begin(); c != rep->trans.end(); ) { Partition *partition = c->second->partition; if (rep->otherwise != *partition->begin()) { c->second = *partition->begin(); c++; } else /* transition is now covered by otherwise */ c = rep->trans.erase(c); } //if ((*p)->size() > 1) //cerr << rep->label << ": "; /* clear the state label for all non representative states, * and accumulate permissions */ for (Partition::iterator i = ++(*p)->begin(); i != (*p)->end(); i++) { //cerr << " " << (*i)->label; if (flags & DFA_DUMP_MIN_PARTS) cerr << **i << ", "; (*i)->label = -1; rep->perms.add((*i)->perms); } if (rep->perms.is_accept()) final_accept++; //if ((*p)->size() > 1) //cerr << "\n"; if (flags & DFA_DUMP_MIN_PARTS) cerr << "\n"; } if (flags & DFA_DUMP_STATS) cerr << "\033[2KMinimized dfa: final partitions " << partitions.size() << " (accept " << final_accept << ")" << "\tinit " << init_count << " (accept " << accept_count << ")\n"; /* make sure nonmatching and start state are up to date with the * mappings */ { Partition *partition = nonmatching->partition; if (*partition->begin() != nonmatching) { nonmatching = *partition->begin(); } partition = start->partition; if (*partition->begin() != start) { start = *partition->begin(); } } /* Now that the states have been remapped, remove all states * that are not the representive states for their partition, they * will have a label == -1 */ for (Partition::iterator i = states.begin(); i != states.end();) { if ((*i)->label == -1) { State *s = *i; i = states.erase(i); delete(s); } else i++; } out: /* Cleanup */ while (!partitions.empty()) { Partition *p = partitions.front(); partitions.pop_front(); delete(p); } } /* diff_encode helper functions */ static unsigned int add_to_dag(DiffDag *dag, State *state, State *parent) { unsigned int rc = 0; if (!state->diff) { dag->rel = NULL; if (parent) dag->depth = parent->diff->depth + 1; else dag->depth = 1; dag->state = state; state->diff = dag; rc = 1; } if (parent && parent->diff->depth < state->diff->depth) state->diff->parents.push_back(parent); return rc; } static int diff_partition(State *state, Partition &part, State **candidate) { int weight = 0; *candidate = NULL; for (Partition::iterator i = part.begin(); i != part.end(); i++) { if (*i == state) continue; int tmp = state->diff_weight(*i); if (tmp > weight) { weight = tmp; *candidate = *i; } } return weight; } /** * diff_encode - compress dfa by differentially encoding state transitions * @dfa_flags: flags controling dfa creation * * This function reduces the number of transitions that need to be stored * by encoding transitions as the difference between the state and a * another transitions that is set as the states default. * * For performance reasons this function does not try to compute the * absolute best encoding (maximal spanning tree) but instead computes * a very good encoding within the following limitations. * - Not all states have to be differentially encoded. This allows for * multiple states to be used as a terminating basis. * - The number of state transitions needed to match an input of length * m will be 2m * * To guarentee this the ordering and distance calculation is done in the * following manner. * - A DAG of the DFA is created starting with the start state(s). * - A state can only be relative (have a differential encoding) to * another state if that state has * - a lower depth in the DAG * - is a sibling (same depth) that is not relative * - is a sibling that is relative to a state with lower depth in the DAG * * The run time constraints are maintained by the DAG ordering + relative * state constraints. For any input character C when at state S with S being * at level N in the DAG then at most 2N states must be traversed to find the * transition for C. However on the maximal number of transitions is not m*m, * because when a character is matched and forward movement is made through * the DFA any relative transition search will move back through the DAG order. * So say for character C we start matching on a state S that is at depth 10 * in the DAG. The transition for C is not found in S and we recurse backwards * to a depth of 6. A transition is found and it steps to the next state, but * the state transition at most will only move 1 deeper into the DAG so for * the next state the maximum number of states traversed is 2*7. */ void DFA::diff_encode(dfaflags_t flags) { DiffDag *dag; unsigned int xcount = 0, xweight = 0, transitions = 0, depth = 0; /* clear the depth flag */ for (Partition::iterator i = states.begin(); i != states.end(); i++) { (*i)->diff = NULL; transitions += (*i)->trans.size(); } /* Prealloc structures we need. We know the exact number of elements, * and once setup they don't change so we don't need the flexibility * or overhead of stl, just allocate the needed data as an array */ dag = new DiffDag [states.size()]; /* Generate DAG ordering and parent sets */ add_to_dag(&dag[0], nonmatching, NULL); add_to_dag(&dag[1], start, NULL); unsigned int tail = 2; for (unsigned int i = 1; i < tail; i++) { State *state = dag[i].state; State *child = dag[i].state->otherwise; if (child) tail += add_to_dag(&dag[tail], child, state); for (StateTrans::iterator j = state->trans.begin(); j != state->trans.end(); j++) { child = j->second; tail += add_to_dag(&dag[tail], child, state); } } depth = dag[tail - 1].depth; /* calculate which state to make a transitions relative too */ for (unsigned int i = 2; i < tail; i++) { State *state = dag[i].state; State *candidate = NULL; int weight = diff_partition(state, state->otherwise->diff->parents, &candidate); for (StateTrans::iterator j = state->trans.begin(); j != state->trans.end(); j++) { State *tmp_candidate; int tmp = diff_partition(state, j->second->diff->parents, &tmp_candidate); if (tmp > weight) { weight = tmp; candidate = tmp_candidate; } } if ((flags & DFA_DUMP_DIFF_PROGRESS) && (i % 100 == 0)) cerr << "\033[2KDiff Encode: " << i << " of " << tail << ". Diff states " << xcount << " Savings " << xweight << "\r"; state->diff->rel = candidate; if (candidate) { xcount++; xweight += weight; } } /* now make transitions relative, start at the back of the list so * as to start with the last transitions and work backwards to avoid * having to traverse multiple previous states (that have been made * relative already) to reconstruct previous state transition table */ unsigned int aweight = 0; diffcount = 0; for (int i = tail - 1; i > 1; i--) { if (dag[i].rel) { int weight = dag[i].state->make_relative(dag[i].rel); aweight += weight; diffcount++; } } if (flags & DFA_DUMP_DIFF_STATS) cerr << "Diff encode states: " << diffcount << " of " << tail << " reached @ depth " << depth << ". " << aweight << " trans removed\n"; if (xweight != aweight) cerr << "Diff encode error: actual savings " << aweight << " != expected " << xweight << "\n"; if (xcount != diffcount) cerr << "Diff encode error: actual count " << diffcount << " != expected " << xcount << " \n"; /* cleanup */ for (unsigned int i = 0; i < tail; i++) dag[i].parents.clear(); delete [] dag; } /** * flatten_differential - remove differential state encoding * * Flatten the dfa back into a flat encoding. */ void DFA::undiff_encode(void) { for (Partition::iterator i = states.begin(); i != states.end(); i++) (*i)->flatten_relative(); diffcount = 0; } void DFA::dump_diff_chain(ostream &os, map &relmap, Partition &chain, State *state, unsigned int &count, unsigned int &total, unsigned int &max) { if (relmap[state].size() == 0) { for (Partition::iterator i = chain.begin(); i != chain.end(); i++) os << **i << " <- "; os << *state << "\n"; count++; total += chain.size() + 1; if (chain.size() + 1 > max) max = chain.size() + 1; } chain.push_back(state); for (Partition::iterator i = relmap[state].begin(); i != relmap[state].end(); i++) dump_diff_chain(os, relmap, chain, *i, count, total, max); chain.pop_back(); } /* Dump the DFA diff_encoding chains */ void DFA::dump_diff_encode(ostream &os) { map rel; Partition base, chain; for (Partition::iterator i = states.begin(); i != states.end(); i++) { if ((*i)->flags & DiffEncodeFlag) rel[(*i)->otherwise].push_back(*i); else base.push_back(*i); } unsigned int count = 0, total = 0, max = 0; for (Partition::iterator i = base.begin(); i != base.end(); i++) dump_diff_chain(os, rel, chain, *i, count, total, max); os << base.size() << " non-differentially encoded states\n"; os << "chains: " << count - base.size() << "\n"; os << "average chain size: " << (double) (total - base.size()) / (double) (count - base.size()) << "\n"; os << "longest chain: " << max << "\n"; } /** * text-dump the DFA (for debugging). */ void DFA::dump(ostream & os) { for (Partition::iterator i = states.begin(); i != states.end(); i++) { if (*i == start || (*i)->perms.is_accept()) { os << **i; if (*i == start) os << " <== (allow/deny/audit/quiet)"; if ((*i)->perms.is_accept()) (*i)->perms.dump(os); os << "\n"; } } os << "\n"; for (Partition::iterator i = states.begin(); i != states.end(); i++) { Chars excluded; for (StateTrans::iterator j = (*i)->trans.begin(); j != (*i)->trans.end(); j++) { if (j->second == nonmatching) { excluded.insert(j->first); } else { os << **i; if ((*i)->perms.is_accept()) os << " ", (*i)->perms.dump(os); os << " -> " << *(j)->second << ": 0x" << hex << (int) j->first; if (isprint(j->first)) os << " " << j->first; os << dec << "\n"; } } if ((*i)->otherwise != nonmatching) { os << **i; if ((*i)->perms.is_accept()) os << " ", (*i)->perms.dump(os); os << " -> " << *(*i)->otherwise << ": ["; if (!excluded.empty()) { os << "^"; for (Chars::iterator k = excluded.begin(); k != excluded.end(); k++) { if (isprint(*k)) os << *k; else os << "\\0x" << hex << (int) *k << dec; } } os << "]\n"; } } os << "\n"; } /** * Create a dot (graphviz) graph from the DFA (for debugging). */ void DFA::dump_dot_graph(ostream & os) { os << "digraph \"dfa\" {" << "\n"; for (Partition::iterator i = states.begin(); i != states.end(); i++) { if (*i == nonmatching) continue; os << "\t\"" << **i << "\" [" << "\n"; if (*i == start) { os << "\t\tstyle=bold" << "\n"; } if ((*i)->perms.is_accept()) { os << "\t\tlabel=\"" << **i << "\\n"; (*i)->perms.dump(os); os << "\"\n"; } os << "\t]" << "\n"; } for (Partition::iterator i = states.begin(); i != states.end(); i++) { Chars excluded; for (StateTrans::iterator j = (*i)->trans.begin(); j != (*i)->trans.end(); j++) { if (j->second == nonmatching) excluded.insert(j->first); else { os << "\t\"" << **i << "\" -> \"" << *j->second << "\" [" << "\n"; os << "\t\tlabel=\""; if (isprint(j->first)) os << j->first; else os << "\\0x" << hex << (int) j->first << dec; os << "\"\n\t]" << "\n"; } } if ((*i)->otherwise != nonmatching) { os << "\t\"" << **i << "\" -> \"" << *(*i)->otherwise << "\" [" << "\n"; if (!excluded.empty()) { os << "\t\tlabel=\"[^"; for (Chars::iterator i = excluded.begin(); i != excluded.end(); i++) { if (isprint(*i)) os << *i; else os << "\\0x" << hex << (int) *i << dec; } os << "]\"" << "\n"; } os << "\t]" << "\n"; } } os << '}' << "\n"; } /** * Compute character equivalence classes in the DFA to save space in the * transition table. */ map DFA::equivalence_classes(dfaflags_t flags) { map classes; uchar next_class = 1; for (Partition::iterator i = states.begin(); i != states.end(); i++) { /* Group edges to the same next state together */ map node_sets; for (StateTrans::iterator j = (*i)->trans.begin(); j != (*i)->trans.end(); j++) node_sets[j->second].insert(j->first); for (map::iterator j = node_sets.begin(); j != node_sets.end(); j++) { /* Group edges to the same next state together by class */ map node_classes; bool class_used = false; for (Chars::iterator k = j->second.begin(); k != j->second.end(); k++) { pair::iterator, bool> x = classes.insert(make_pair(*k, next_class)); if (x.second) class_used = true; pair::iterator, bool> y = node_classes.insert(make_pair(x.first->second, Chars())); y.first->second.insert(*k); } if (class_used) { next_class++; class_used = false; } for (map::iterator k = node_classes.begin(); k != node_classes.end(); k++) { /** * If any other characters are in the same class, move * the characters in this class into their own new * class */ map::iterator l; for (l = classes.begin(); l != classes.end(); l++) { if (l->second == k->first && k->second.find(l->first) == k->second.end()) { class_used = true; break; } } if (class_used) { for (Chars::iterator l = k->second.begin(); l != k->second.end(); l++) { classes[*l] = next_class; } next_class++; class_used = false; } } } } if (flags & DFA_DUMP_EQUIV_STATS) fprintf(stderr, "Equiv class reduces to %d classes\n", next_class - 1); return classes; } /** * Text-dump the equivalence classes (for debugging). */ void dump_equivalence_classes(ostream &os, map &eq) { map rev; for (map::iterator i = eq.begin(); i != eq.end(); i++) { Chars &chars = rev.insert(make_pair(i->second, Chars())).first->second; chars.insert(i->first); } os << "(eq):" << "\n"; for (map::iterator i = rev.begin(); i != rev.end(); i++) { os << (int)i->first << ':'; Chars &chars = i->second; for (Chars::iterator j = chars.begin(); j != chars.end(); j++) { os << ' ' << *j; } os << "\n"; } } /** * Replace characters with classes (which are also represented as * characters) in the DFA transition table. */ void DFA::apply_equivalence_classes(map &eq) { /** * Note: We only transform the transition table; the nodes continue to * contain the original characters. */ for (Partition::iterator i = states.begin(); i != states.end(); i++) { map tmp; tmp.swap((*i)->trans); for (StateTrans::iterator j = tmp.begin(); j != tmp.end(); j++) (*i)->trans.insert(make_pair(eq[j->first], j->second)); } } #if 0 typedef set AcceptNodes; map dominance(DFA & dfa) { map is_dominated; for (States::iterator i = dfa.states.begin(); i != dfa.states.end(); i++) { AcceptNodes set1; for (State::iterator j = (*i)->begin(); j != (*i)->end(); j++) { if (AcceptNode * accept = dynamic_cast(*j)) set1.insert(accept); } for (AcceptNodes::iterator j = set1.begin(); j != set1.end(); j++) { pair::iterator, bool> x = is_dominated.insert(make_pair(*j, set1)); if (!x.second) { AcceptNodes & set2(x.first->second), set3; for (AcceptNodes::iterator l = set2.begin(); l != set2.end(); l++) { if (set1.find(*l) != set1.end()) set3.insert(*l); } set3.swap(set2); } } } return is_dominated; } #endif static inline int diff_qualifiers(uint32_t perm1, uint32_t perm2) { return ((perm1 & AA_EXEC_TYPE) && (perm2 & AA_EXEC_TYPE) && (perm1 & AA_EXEC_TYPE) != (perm2 & AA_EXEC_TYPE)); } /** * Compute the permission flags that this state corresponds to. If we * have any exact matches, then they override the execute and safe * execute flags. */ int accept_perms(NodeSet *state, perms_t &perms) { int error = 0; uint32_t exact_match_allow = 0; uint32_t exact_audit = 0; perms.clear(); if (!state) return error; for (NodeSet::iterator i = state->begin(); i != state->end(); i++) { MatchFlag *match; if (!(match = dynamic_cast(*i))) continue; if (dynamic_cast(match)) { /* exact match only ever happens with x */ if (!is_merged_x_consistent(exact_match_allow, match->flag)) error = 1;; exact_match_allow |= match->flag; exact_audit |= match->audit; } else if (dynamic_cast(match)) { perms.deny |= match->flag; perms.quiet |= match->audit; } else { if (!is_merged_x_consistent(perms.allow, match->flag)) error = 1; perms.allow |= match->flag; perms.audit |= match->audit; } } perms.allow |= exact_match_allow & ~(ALL_AA_EXEC_TYPE); perms.audit |= exact_audit & ~(ALL_AA_EXEC_TYPE); if (exact_match_allow & AA_USER_EXEC) { perms.allow = (exact_match_allow & AA_USER_EXEC_TYPE) | (perms.allow & ~AA_USER_EXEC_TYPE); perms.exact = AA_USER_EXEC_TYPE; } if (exact_match_allow & AA_OTHER_EXEC) { perms.allow = (exact_match_allow & AA_OTHER_EXEC_TYPE) | (perms.allow & ~AA_OTHER_EXEC_TYPE); perms.exact |= AA_OTHER_EXEC_TYPE; } if (AA_USER_EXEC & perms.deny) perms.deny |= AA_USER_EXEC_TYPE; if (AA_OTHER_EXEC & perms.deny) perms.deny |= AA_OTHER_EXEC_TYPE; perms.allow &= ~perms.deny; perms.quiet &= perms.deny; if (error) fprintf(stderr, "profile has merged rule with conflicting x modifiers\n"); return error; } apparmor-2.13.3/parser/libapparmor_re/apparmor_re.h0000644000175000017500000000402013502024172020153 0ustar jjjj/* * (C) 2006, 2007 Andreas Gruenbacher * Copyright (c) 2003-2008 Novell, Inc. (All rights reserved) * Copyright 2009-2012 Canonical Ltd. * * The libapparmor library is licensed under the terms of the GNU * Lesser General Public License, version 2.1. Please see the file * COPYING.LGPL. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef APPARMOR_RE_H #define APPARMOR_RE_H typedef int dfaflags_t; #define DFA_CONTROL_EQUIV (1 << 0) #define DFA_CONTROL_TREE_NORMAL (1 << 1) #define DFA_CONTROL_TREE_SIMPLE (1 << 2) #define DFA_CONTROL_TREE_LEFT (1 << 3) #define DFA_CONTROL_MINIMIZE (1 << 4) #define DFA_CONTROL_FILTER_DENY (1 << 6) #define DFA_CONTROL_REMOVE_UNREACHABLE (1 << 7) #define DFA_CONTROL_TRANS_HIGH (1 << 8) #define DFA_CONTROL_DIFF_ENCODE (1 << 9) #define DFA_DUMP_DIFF_PROGRESS (1 << 10) #define DFA_DUMP_DIFF_ENCODE (1 << 11) #define DFA_DUMP_DIFF_STATS (1 << 12) #define DFA_DUMP_MIN_PARTS (1 << 13) #define DFA_DUMP_UNIQ_PERMS (1 << 14) #define DFA_DUMP_MIN_UNIQ_PERMS (1 << 15) #define DFA_DUMP_TREE_STATS (1 << 16) #define DFA_DUMP_TREE (1 << 17) #define DFA_DUMP_SIMPLE_TREE (1 << 18) #define DFA_DUMP_PROGRESS (1 << 19) #define DFA_DUMP_STATS (1 << 20) #define DFA_DUMP_STATES (1 << 21) #define DFA_DUMP_GRAPH (1 << 22) #define DFA_DUMP_TRANS_PROGRESS (1 << 23) #define DFA_DUMP_TRANS_STATS (1 << 24) #define DFA_DUMP_TRANS_TABLE (1 << 25) #define DFA_DUMP_EQUIV (1 << 26) #define DFA_DUMP_EQUIV_STATS (1 << 27) #define DFA_DUMP_MINIMIZE (1 << 28) #define DFA_DUMP_UNREACHABLE (1 << 29) #define DFA_DUMP_RULE_EXPR (1 << 30) #define DFA_DUMP_NODE_TO_DFA (1 << 31) #endif /* APPARMOR_RE_H */ apparmor-2.13.3/parser/policydb.h0000644000175000017500000000214013502024172014454 0ustar jjjj/* * Copyright 2012 Canonical Ltd. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, version 2 of the * License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #ifndef __AA_POLICYDB_H #define __AA_POLICYDB_H /* * Class of private mediation types in the AppArmor policy db * * See libapparmor's apparmor.h for public mediation types */ #define AA_CLASS_COND 0 #define AA_CLASS_UNKNOWN 1 #define AA_CLASS_FILE 2 #define AA_CLASS_CAP 3 #define AA_CLASS_NET 4 #define AA_CLASS_RLIMITS 5 #define AA_CLASS_DOMAIN 6 #define AA_CLASS_MOUNT 7 #define AA_CLASS_NS_DOMAIN 8 #define AA_CLASS_PTRACE 9 #define AA_CLASS_SIGNAL 10 #define AA_CLASS_LABEL 16 /* defined in libapparmor's apparmor.h #define AA_CLASS_DBUS 32 */ #define AA_CLASS_X 33 #endif /* __AA_POLICYDB_H */ apparmor-2.13.3/parser/aa-teardown.80000644000175000017500000001035213502024374015001 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "AA-TEARDOWN 8" .TH AA-TEARDOWN 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" aa\-teardown \- unload all AppArmor profiles .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBaa-teardown\fR .SH "DESCRIPTION" .IX Header "DESCRIPTION" aa-teardown unloads all AppArmor profiles .SH "BUGS" .IX Header "BUGS" If you find any bugs, please report them at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7), \fIapparmor.d\fR\|(5), and . apparmor-2.13.3/parser/apparmor_parser.80000644000175000017500000004253213502024374016001 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "APPARMOR_PARSER 8" .TH APPARMOR_PARSER 8 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" apparmor_parser \- loads AppArmor profiles into the kernel .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBapparmor_parser [options] [profiles]...\fR .PP \&\fBapparmor_parser [options] \fR .PP \&\fBapparmor_parser [\-hv] [\-\-help] [\-\-version]\fR .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBapparmor_parser\fR is used as a general tool to compile, and manage AppArmor policy, including loading new \fIapparmor.d\fR\|(5) profiles into the Linux kernel. .PP AppArmor profiles restrict the operations available to processes. .PP The \fBprofiles\fR are loaded into the Linux kernel by the \fBapparmor_parser\fR program. The \fBprofiles\fR may be specified by file name or a directory name containing a set of profiles. If a directory is specified then the \&\fBapparmor_parser\fR will try to do a profile load for each file in the directory that is not a dot file, or explicitly black listed (*.dpkg\-new, *.dpkg\-old, *.dpkg\-dist, *.dpkg\-bak, *.dpkg\-remove, *.pacsave, *.pacnew, *.rpmnew, *.rpmsave, *.orig, *.rej, *~). The \fBapparmor_parser\fR will fall back to taking input from standard input if a profile or directory is not supplied. .PP The input supplied to \fBapparmor_parser\fR should be in the format described in \&\fIapparmor.d\fR\|(5). .SH "COMMANDS" .IX Header "COMMANDS" The command set is broken into four subcategories. .IP "unprivileged commands" 4 .IX Item "unprivileged commands" Commands that don't require any privilege and don't operate on profiles. .IP "unprivileged profile commands" 4 .IX Item "unprivileged profile commands" Commands that operate on a profile either specified on the command line or read from stdin if no profile was specified. .IP "privileged commands" 4 .IX Item "privileged commands" Commands that require the \s-1MAC_ADMIN\s0 capability within the affected AppArmor namespace to load policy into the kernel or filesystem write permissions to update the affected privileged files (cache etc). .IP "privileged profile commands" 4 .IX Item "privileged profile commands" Commands that require privilege and operate on profiles. .SH "Unprivileged commands" .IX Header "Unprivileged commands" .IP "\-V, \-\-version" 4 .IX Item "-V, --version" Print the version number and exit. .IP "\-h, \-\-help" 4 .IX Item "-h, --help" Give a quick reference guide. .SH "Unprivileged profile commands" .IX Header "Unprivileged profile commands" .IP "\-N, \-\-names" 4 .IX Item "-N, --names" Produce a list of policies from a given set of profiles (implies \-K). .IP "\-p, \-\-preprocess" 4 .IX Item "-p, --preprocess" Apply preprocessing to the input profile(s) by flattening includes into the output profile and dump to stdout. .IP "\-S, \-\-stdout" 4 .IX Item "-S, --stdout" Writes a binary (cached) profile to stdout (implies \-K and \-T). .IP "\-o file, \-\-ofile file" 4 .IX Item "-o file, --ofile file" Writes a binary (cached) profile to the specified file (implies \-K and \-T) .SH "Privileged commands" .IX Header "Privileged commands" .IP "\-\-purge\-cache" 4 .IX Item "--purge-cache" Unconditionally clear out cached profiles. .SH "Privileged profile commands" .IX Header "Privileged profile commands" .IP "\-a, \-\-add" 4 .IX Item "-a, --add" Insert the AppArmor definitions given into the kernel. This is the default action. This gives an error message if a AppArmor definition by the same name already exists in the kernel, or if the parser doesn't understand its input. It reports when an addition succeeded. .IP "\-r, \-\-replace" 4 .IX Item "-r, --replace" This flag is required if an AppArmor definition by the same name already exists in the kernel; used to replace the definition already in the kernel with the definition given on standard input. .IP "\-R, \-\-remove" 4 .IX Item "-R, --remove" This flag is used to remove an AppArmor definition already in the kernel. Note that it still requires a complete AppArmor definition as described in \fIapparmor.d\fR\|(5) even though the contents of the definition aren't used. .SH "OPTIONS" .IX Header "OPTIONS" .IP "\-B, \-\-binary" 4 .IX Item "-B, --binary" Treat the profile files specified on the command line (or stdin if none specified) as binary cache files, produced with the \-S or \-o options, and load to the kernel as specified by \-a, \-r, and \-R (implies \-K and \-T). .IP "\-C, \-\-Complain" 4 .IX Item "-C, --Complain" Force the profile to load in complain mode. .IP "\-b n, \-\-base n" 4 .IX Item "-b n, --base n" Set the base directory for resolving #include directives defined as relative paths. .IP "\-I n, \-\-Include n" 4 .IX Item "-I n, --Include n" Add element n to the search path when resolving #include directives defined as an absolute paths. .IP "\-f n, \-\-subdomainfs n" 4 .IX Item "-f n, --subdomainfs n" Set the location of the apparmor security filesystem (default is \&\*(L"/sys/kernel/security/apparmor\*(R"). .IP "\-M n, \-\-features\-file n" 4 .IX Item "-M n, --features-file n" Use the features file located at path \*(L"n\*(R" (default is /etc/apparmor.d/cache/.features). If the \-\-cache\-loc option is present, the \&\*(L".features\*(R" file in the specified cache directory is used. .IP "\-m n, \-\-match\-string n" 4 .IX Item "-m n, --match-string n" Only use match features \*(L"n\*(R". .IP "\-n n, \-\-namespace\-string n" 4 .IX Item "-n n, --namespace-string n" Force a profile to load in the namespace \*(L"n\*(R". .IP "\-X, \-\-readimpliesX" 4 .IX Item "-X, --readimpliesX" In the case of profiles that are loading on systems were \s-1READ_IMPLIES_EXEC\s0 is set in the kernel for a given process, load the profile so that any \*(L"r\*(R" flags are processed as \*(L"mr\*(R". .IP "\-k, \-\-show\-cache" 4 .IX Item "-k, --show-cache" Report the cache processing (hit/miss details) when loading or saving cached profiles. .IP "\-K, \-\-skip\-cache" 4 .IX Item "-K, --skip-cache" Perform no caching at all: disables \-W, implies \-T. .IP "\-T, \-\-skip\-read\-cache" 4 .IX Item "-T, --skip-read-cache" By default, if a profile's cache is found in the location specified by \&\-\-cache\-loc and the timestamp is newer than the profile, it will be loaded from the cache. This option disables this cache loading behavior. .IP "\-W, \-\-write\-cache" 4 .IX Item "-W, --write-cache" Write out cached profiles to the location specified in \-\-cache\-loc. Off by default. In cases where abstractions have been changed, and the parser is running with \*(L"\-\-replace\*(R", it may make sense to also use \&\*(L"\-\-skip\-read\-cache\*(R" with the \*(L"\-\-write\-cache\*(R" option. .IP "\-\-skip\-bad\-cache" 4 .IX Item "--skip-bad-cache" Skip updating the cache if it contains cached profiles in a bad or inconsistent state .IP "\-L, \-\-cache\-loc" 4 .IX Item "-L, --cache-loc" Set the location(s) of the cache directory. This option can accept a comma separated list of directories, which will be searched in order to find a matching cache. The first matching cache file found is used even if a directory later in the search order may contain a newer cache file. .Sp If multiple directories are specified and \-\-write\-cache has been specified then cache writes will be made to the first directory in the list, all other directories will be treated as read only. .Sp If a cache directory name needs to have a comma as part of the name, it can be specified by using a backslash to escape the comma character in the directory name. .Sp If not specified the cache location defaults to /var/cache/apparmor .IP "\-\-print\-cache\-dir" 4 .IX Item "--print-cache-dir" Print the cache directory location. This path will be a subdirectory of the directory specified by \-\-cache\-loc. The subdirectory used will be influenced by the features available in the currently running kernel or by the features specified with the \-\-match\-string or \-\-features\-file options. .IP "\-Q, \-\-skip\-kernel\-load" 4 .IX Item "-Q, --skip-kernel-load" Perform all actions except the actual loading of a profile into the kernel. This is useful for testing profile generation, caching, etc, without making changes to the running kernel profiles. .Sp This also removes the need for privilege to execute the commands that manage policy in the kernel .IP "\-q, \-\-quiet" 4 .IX Item "-q, --quiet" Do not report on the profiles as they are loaded, and not show warnings. .IP "\-v, \-\-verbose" 4 .IX Item "-v, --verbose" Report on the profiles as they are loaded, and show warnings. .IP "\-\-warn=n" 4 .IX Item "--warn=n" Enable various warnings during policy compilation. A single dump flag can be specified per \-\-warn option, but the \-\-warn flag can be passed multiple times. .Sp .Vb 1 \& apparmor_parser \-\-warn=rules\-not\-enforced ... .Ve .Sp Use \-\-help=warn to see a full list of which warn flags are supported. .IP "\-d, \-\-debug" 4 .IX Item "-d, --debug" Given once, only checks the profiles to ensure syntactic correctness. Given twice, dumps its interpretation of the profile for checking. .IP "\-D n, \-\-dump=n" 4 .IX Item "-D n, --dump=n" Debug flag for dumping various structures and passes of policy compilation. A single dump flag can be specified per \-\-dump option, but the dump flag can be passed multiple times. Note progress flags tend to also imply the matching stats flag. .Sp .Vb 1 \& apparmor_parser \-\-dump=dfa\-stats \-\-dump=trans\-stats .Ve .Sp Use \-\-help=dump to see a full list of which dump flags are supported .IP "\-j n, \-\-jobs=n" 4 .IX Item "-j n, --jobs=n" Set the number of jobs used to compile the specified policy. Where n can be .Sp .Vb 3 \& # \- a specific number of jobs \& auto \- the # of cpus in the in the system \& x# \- # * number of cpus .Ve .Sp Eg. \-j8 \s-1OR\s0 \-\-jobs=8 allows for 8 parallel jobs \-jauto \s-1OR\s0 \-\-jobs=auto sets the jobs to the # of cpus \-jx4 \s-1OR\s0 \-\-jobs=x4 sets the jobs to # of cpus * 4 \-jx1 is equivalent to \-jauto .Sp The default value is the number of cpus in the system. .IP "\-\-max\-jobs n" 4 .IX Item "--max-jobs n" Set a hard cap on the value that can be specified by the \-\-jobs flag. It takes the same set of options available to the \-\-jobs option, and defaults to 8*cpus .IP "\-O n, \-\-optimize=n" 4 .IX Item "-O n, --optimize=n" Set the optimization flags used by policy compilation. A single optimization flag can be toggled per \-O option, but the optimize flag can be passed multiple times. Turning off some phases of the optimization can make it so that policy can't complete compilation due to size constraints (it is entirely possible to create a dfa with millions of states that will take days or longer to compile). .Sp Note: The parser is set to use a balanced default set of flags, that will result in reasonable compression but not take excessive amounts of time to complete. .Sp Use \-\-help=optimize to see a full list of which optimization flags are supported. .IP "\-\-abort\-on\-error Abort processing of profiles on the first error encountered, otherwise the parser will continue to try to compile other profiles if specified." 4 .IX Item "--abort-on-error Abort processing of profiles on the first error encountered, otherwise the parser will continue to try to compile other profiles if specified." Note: If an error is encountered while processing profiles the last error encountered will be used to set the exit code. .IP "\-\-skip\-bad\-cache\-rebuild The default behavior of the parser is to check if a cached version of a profile exists and if it does it attempt to load it into the kernel. If that load is rejected, then the parser will attempt to rebuild the cache file, and load again." 4 .IX Item "--skip-bad-cache-rebuild The default behavior of the parser is to check if a cached version of a profile exists and if it does it attempt to load it into the kernel. If that load is rejected, then the parser will attempt to rebuild the cache file, and load again." This option tells the parser to not attempt to rebuild the cache on failure, instead the parser continues on with processing the remaining profiles. .IP "\-\-config\-file" 4 .IX Item "--config-file" Specify the config file to use instead of /etc/apparmor/parser.conf. This option will be processed early before regular options regardless of the order it is specified in. .IP "\-\-print\-config\-file" 4 .IX Item "--print-config-file" Print the config file location that will be used. .SH "CONFIG FILE" .IX Header "CONFIG FILE" An optional config file /etc/apparmor/parser.conf can be used to specify the default options for the parser, which then can be overridden using the command line options. .PP The config file ignores leading whitespace and treats lines that begin with # as comments. Config options are specified one per line using the same format as the longform command line options (without the preceding \-\-). .PP Eg. #comment .PP .Vb 2 \& optimize=no\-expr\-tree \& optimize=compress\-fast .Ve .PP As with the command line some options accumulate and others override, ie. when there are conflicting versions of switch the last option is the one chosen. .PP Eg. Optimize=no\-minimize Optimize=minimize .PP would result in Optimize=minimize being set. .PP The Include, Dump, and Optimize options accululate except for the inversion option (no-X vs. X), and a couple options that work by setting/clearing multiple options (compress-small). In that case the option will override the flags it sets but will may accumulate with others. .PP All other options override previously set values. .SH "BUGS" .IX Header "BUGS" If you find any bugs, please report them at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7), \fIapparmor.d\fR\|(5), \fIsubdomain.conf\fR\|(5), \fIaa_change_hat\fR\|(2), and . apparmor-2.13.3/parser/apparmor.7.html0000644000175000017500000002233113502024374015362 0ustar jjjj
 

NAME

AppArmor - kernel enhancement to confine programs to a limited set of resources.

DESCRIPTION

AppArmor is a kernel enhancement to confine programs to a limited set of resources. AppArmor's unique security model is to bind access control attributes to programs rather than to users.

AppArmor confinement is provided via profiles loaded into the kernel via apparmor_parser(8), typically through the /etc/init.d/apparmor SysV initscript, which is used like this:

        # /etc/init.d/apparmor start
        # /etc/init.d/apparmor stop
        # /etc/init.d/apparmor restart

AppArmor can operate in two modes: enforcement, and complain or learning:

  • enforcement - Profiles loaded in enforcement mode will result in enforcement of the policy defined in the profile as well as reporting policy violation attempts to syslogd.

  • complain - Profiles loaded in complain mode will not enforce policy. Instead, it will report policy violation attempts. This mode is convenient for developing profiles. To manage complain mode for individual profiles the utilities aa-complain(8) and aa-enforce(8) can be used. These utilities take a program name as an argument.

Profiles are traditionally stored in files in /etc/apparmor.d/ under filenames with the convention of replacing the / in pathnames with . (except for the root /) so profiles are easier to manage (e.g. the /usr/sbin/nscd profile would be named usr.sbin.nscd).

Profiles are applied to a process at exec(3) time (as seen through the execve(2) system call): once a profile is loaded for a program, that program will be confined on the next exec(3). If a process is already running under a profile, when one replaces that profile in the kernel, the updated profile is applied immediately to that process. On the other hand, a process that is already running unconfined cannot be confined.

AppArmor supports the Linux kernel's securityfs filesystem, and makes available the list of the profiles currently loaded; to mount the filesystem:

        # mount -tsecurityfs securityfs /sys/kernel/security
        $ cat /sys/kernel/security/apparmor/profiles
        /usr/bin/mutt
        /usr/bin/gpg
           ...

Normally, the initscript will mount securityfs if it has not already been done.

AppArmor also restricts what privileged operations a confined process may execute, even if the process is running as root. A confined process cannot call the following system calls:

        create_module(2) delete_module(2) init_module(2) ioperm(2)
        iopl(2) ptrace(2) reboot(2) setdomainname(2)
        sethostname(2) swapoff(2) swapon(2) sysctl(2)

ERRORS

When a confined process tries to access a file it does not have permission to access, the kernel will report a message through audit, similar to:

        audit(1386511672.612:238): apparmor="DENIED" operation="exec" 
          parent=7589 profile="/tmp/sh" name="/bin/uname" pid=7605 
          comm="sh" requested_mask="x" denied_mask="x" fsuid=0 ouid=0

        audit(1386511672.613:239): apparmor="DENIED" operation="open" 
          parent=7589 profile="/tmp/sh" name="/bin/uname" pid=7605 
          comm="sh" requested_mask="r" denied_mask="r" fsuid=0 ouid=0

        audit(1386511772.804:246): apparmor="DENIED" operation="capable"
          parent=7246 profile="/tmp/sh" pid=7589 comm="sh" pid=7589 
          comm="sh" capability=2  capname="dac_override"

The permissions requested by the process are described in the operation= and denied_mask= (for files - capabilities etc. use a slightly different log format). The "name" and process id of the running program are reported, as well as the profile name including any "hat" that may be active, separated by "//". ("Name" is in quotes, because the process name is limited to 15 bytes; it is the same as reported through the Berkeley process accounting.)

For confined processes running under a profile that has been loaded in complain mode, enforcement will not take place and the log messages reported to audit will be of the form:

        audit(1386512577.017:275): apparmor="ALLOWED" operation="open"
          parent=8012 profile="/usr/bin/du" name="/etc/apparmor.d/tunables/"
          pid=8049 comm="du" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0

        audit(1386512577.017:276): apparmor="ALLOWED" operation="open"
          parent=8012 profile="/usr/bin/du" name="/etc/apparmor.d/tunables/"
          pid=8049 comm="du" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0

If the userland auditd is not running, the kernel will send audit events to klogd; klogd will send the messages to syslog, which will log the messages with the KERN facility. Thus, REJECTING and PERMITTING messages may go to either /var/log/audit/audit.log or /var/log/messages, depending upon local configuration.

DEBUGGING

AppArmor provides a few facilities to log more information, which can help debugging profiles.

Enable debug mode

When debug mode is enabled, AppArmor will log a few extra messages to dmesg (not via the audit subsystem). For example, the logs will tell whether environment scrubbing has been applied.

To enable debug mode, run:

        echo 1 > /sys/module/apparmor/parameters/debug

Turn off deny audit quieting

By default, operations that trigger deny rules are not logged. This is called deny audit quieting.

To turn off deny audit quieting, run:

        echo -n noquiet >/sys/module/apparmor/parameters/audit

Force audit mode

AppArmor can log a message for every operation that triggers a rule configured in the policy. This is called force audit mode.

Warning! Force audit mode can be extremely noisy even for a single profile, let alone when enabled globally.

To set a specific profile in force audit mode, add the audit flag:

        profile foo flags=(audit) { ... }

To enable force audit mode globally, run:

        echo -n all > /sys/module/apparmor/parameters/audit

If auditd is not running, to avoid losing too many of the extra log messages, you will likely have to turn off rate limiting by doing:

        echo 0 > /proc/sys/kernel/printk_ratelimit

But even then the kernel ring buffer may overflow and you might lose messages.

Else, if auditd is running, see auditd(8) and auditd.conf(5).

FILES

/etc/init.d/apparmor
/etc/apparmor.d/
/var/lib/apparmor/
/var/log/audit/audit.log
/var/log/messages

SEE ALSO

apparmor_parser(8), aa_change_hat(2), apparmor.d(5), subdomain.conf(5), aa-autodep(1), clean(1), auditd(8), aa-unconfined(8), aa-enforce(1), aa-complain(1), and https://wiki.apparmor.net.

 
apparmor-2.13.3/parser/parser_interface.c0000644000175000017500000003266713502024172016177 0ustar jjjj/* * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 * NOVELL (All rights reserved) * * Copyright (c) 2013 * Canonical Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. */ #include #include #include #include #include #include #include #include #include #include "lib.h" #include "parser.h" #include "profile.h" #include "libapparmor_re/apparmor_re.h" #include #include #define SD_CODE_SIZE (sizeof(u8)) #define SD_STR_LEN (sizeof(u16)) int __sd_serialize_profile(int option, aa_kernel_interface *kernel_interface, Profile *prof, int cache_fd); static void print_error(int error) { switch (error) { case -ESPIPE: PERROR(_("Bad write position\n")); break; case -EPERM: PERROR(_("Permission denied\n")); break; case -ENOMEM: PERROR(_("Out of memory\n")); break; case -EFAULT: PERROR(_("Couldn't copy profile: Bad memory address\n")); break; case -EPROTO: PERROR(_("Profile doesn't conform to protocol\n")); break; case -EBADMSG: PERROR(_("Profile does not match signature\n")); break; case -EPROTONOSUPPORT: PERROR(_("Profile version not supported by Apparmor module\n")); break; case -EEXIST: PERROR(_("Profile already exists\n")); break; case -ENOENT: PERROR(_("Profile doesn't exist\n")); break; case -EACCES: PERROR(_("Permission denied; attempted to load a profile while confined?\n")); break; default: PERROR(_("Unknown error (%d): %s\n"), -error, strerror(-error)); break; } } int load_profile(int option, aa_kernel_interface *kernel_interface, Profile *prof, int cache_fd) { int retval = 0; int error = 0; PDEBUG("Serializing policy for %s.\n", prof->name); retval = __sd_serialize_profile(option, kernel_interface, prof, cache_fd); if (retval < 0) { error = retval; /* yeah, we'll just report the last error */ switch (option) { case OPTION_ADD: PERROR(_("%s: Unable to add \"%s\". "), progname, prof->name); print_error(error); break; case OPTION_REPLACE: PERROR(_("%s: Unable to replace \"%s\". "), progname, prof->name); print_error(error); break; case OPTION_REMOVE: PERROR(_("%s: Unable to remove \"%s\". "), progname, prof->name); print_error(error); break; case OPTION_STDOUT: PERROR(_("%s: Unable to write to stdout\n"), progname); break; case OPTION_OFILE: PERROR(_("%s: Unable to write to output file\n"), progname); default: PERROR(_("%s: ASSERT: Invalid option: %d\n"), progname, option); exit(1); break; } } else if (conf_verbose) { switch (option) { case OPTION_ADD: printf(_("Addition succeeded for \"%s\".\n"), prof->name); break; case OPTION_REPLACE: printf(_("Replacement succeeded for \"%s\".\n"), prof->name); break; case OPTION_REMOVE: printf(_("Removal succeeded for \"%s\".\n"), prof->name); break; case OPTION_STDOUT: case OPTION_OFILE: break; default: PERROR(_("%s: ASSERT: Invalid option: %d\n"), progname, option); exit(1); break; } } return error; } enum sd_code { SD_U8, SD_U16, SD_U32, SD_U64, SD_NAME, /* same as string except it is items name */ SD_STRING, SD_BLOB, SD_STRUCT, SD_STRUCTEND, SD_LIST, SD_LISTEND, SD_ARRAY, SD_ARRAYEND, SD_OFFSET }; const char *sd_code_names[] = { "SD_U8", "SD_U16", "SD_U32", "SD_U64", "SD_NAME", "SD_STRING", "SD_BLOB", "SD_STRUCT", "SD_STRUCTEND", "SD_LIST", "SD_LISTEND", "SD_ARRAY", "SD_ARRAYEND", "SD_OFFSET" }; static inline void sd_write8(std::ostringstream &buf, u8 b) { buf.write((const char *) &b, 1); } static inline void sd_write16(std::ostringstream &buf, u16 b) { u16 tmp; tmp = cpu_to_le16(b); buf.write((const char *) &tmp, 2); } static inline void sd_write32(std::ostringstream &buf, u32 b) { u32 tmp; tmp = cpu_to_le32(b); buf.write((const char *) &tmp, 4); } static inline void sd_write64(std::ostringstream &buf, u64 b) { u64 tmp; tmp = cpu_to_le64(b); buf.write((const char *) &tmp, 8); } static inline void sd_write_uint8(std::ostringstream &buf, u8 b) { sd_write8(buf, SD_U8); sd_write8(buf, b); } static inline void sd_write_uint16(std::ostringstream &buf, u16 b) { sd_write8(buf, SD_U16); sd_write16(buf, b); } static inline void sd_write_uint32(std::ostringstream &buf, u32 b) { sd_write8(buf, SD_U32); sd_write32(buf, b); } static inline void sd_write_uint64(std::ostringstream &buf, u64 b) { sd_write8(buf, SD_U64); sd_write64(buf, b); } static inline void sd_write_name(std::ostringstream &buf, const char *name) { PDEBUG("Writing name '%s'\n", name); if (name) { sd_write8(buf, SD_NAME); sd_write16(buf, strlen(name) + 1); buf.write(name, strlen(name) + 1); } } static inline void sd_write_blob(std::ostringstream &buf, void *b, int buf_size, char *name) { sd_write_name(buf, name); sd_write8(buf, SD_BLOB); sd_write32(buf, buf_size); buf.write((const char *) b, buf_size); } static char zeros[64]; #define align64(X) (((X) + (typeof(X)) 7) & ~((typeof(X)) 7)) static inline void sd_write_aligned_blob(std::ostringstream &buf, void *b, int b_size, const char *name) { sd_write_name(buf, name); /* pad calculation MUST come after name is written */ size_t pad = align64(buf.tellp() + ((std::streamoff) 5l)) - (buf.tellp() + ((std::streamoff) 5l)); sd_write8(buf, SD_BLOB); sd_write32(buf, b_size + pad); buf.write(zeros, pad); buf.write((const char *) b, b_size); } static void sd_write_strn(std::ostringstream &buf, char *b, int size, const char *name) { sd_write_name(buf, name); sd_write8(buf, SD_STRING); sd_write16(buf, size); buf.write(b, size); } static inline void sd_write_string(std::ostringstream &buf, char *b, const char *name) { sd_write_strn(buf, b, strlen(b) + 1, name); } static inline void sd_write_struct(std::ostringstream &buf, const char *name) { sd_write_name(buf, name); sd_write8(buf, SD_STRUCT); } static inline void sd_write_structend(std::ostringstream &buf) { sd_write8(buf, SD_STRUCTEND); } static inline void sd_write_array(std::ostringstream &buf, const char *name, int size) { sd_write_name(buf, name); sd_write8(buf, SD_ARRAY); sd_write16(buf, size); } static inline void sd_write_arrayend(std::ostringstream &buf) { sd_write8(buf, SD_ARRAYEND); } static inline void sd_write_list(std::ostringstream &buf, const char *name) { sd_write_name(buf, name); sd_write8(buf, SD_LIST); } static inline void sd_write_listend(std::ostringstream &buf) { sd_write8(buf, SD_LISTEND); } void sd_serialize_dfa(std::ostringstream &buf, void *dfa, size_t size) { if (dfa) sd_write_aligned_blob(buf, dfa, size, "aadfa"); } void sd_serialize_rlimits(std::ostringstream &buf, struct aa_rlimits *limits) { if (!limits->specified) return; sd_write_struct(buf, "rlimits"); sd_write_uint32(buf, limits->specified); sd_write_array(buf, NULL, RLIM_NLIMITS); for (int i = 0; i < RLIM_NLIMITS; i++) { sd_write_uint64(buf, limits->limits[i]); } sd_write_arrayend(buf); sd_write_structend(buf); } void sd_serialize_xtable(std::ostringstream &buf, char **table) { int count; if (!table[4]) return; sd_write_struct(buf, "xtable"); count = 0; for (int i = 4; i < AA_EXEC_COUNT; i++) { if (table[i]) count++; } sd_write_array(buf, NULL, count); for (int i = 4; i < count + 4; i++) { int len = strlen(table[i]) + 1; /* if its a namespace make sure the second : is overwritten * with 0, so that the namespace and name are \0 seperated */ if (*table[i] == ':') { char *tmp = table[i] + 1; strsep(&tmp, ":"); } sd_write_strn(buf, table[i], len, NULL); } sd_write_arrayend(buf); sd_write_structend(buf); } void sd_serialize_profile(std::ostringstream &buf, Profile *profile, int flattened) { uint64_t allowed_caps; sd_write_struct(buf, "profile"); if (flattened) { assert(profile->parent); autofree char *name = (char *) malloc(3 + strlen(profile->name) + strlen(profile->parent->name)); if (!name) return; sprintf(name, "%s//%s", profile->parent->name, profile->name); sd_write_string(buf, name, NULL); } else { sd_write_string(buf, profile->name, NULL); } /* only emit this if current kernel at least supports "create" */ if (perms_create) { if (profile->xmatch) { sd_serialize_dfa(buf, profile->xmatch, profile->xmatch_size); sd_write_uint32(buf, profile->xmatch_len); } } sd_write_struct(buf, "flags"); /* used to be flags.debug, but that's no longer supported */ sd_write_uint32(buf, profile->flags.hat); sd_write_uint32(buf, profile->flags.complain); sd_write_uint32(buf, profile->flags.audit); sd_write_structend(buf); if (profile->flags.path) { int flags = 0; if (profile->flags.path & PATH_CHROOT_REL) flags |= 0x8; if (profile->flags.path & PATH_MEDIATE_DELETED) flags |= 0x10000; if (profile->flags.path & PATH_ATTACH) flags |= 0x4; if (profile->flags.path & PATH_CHROOT_NSATTACH) flags |= 0x10; sd_write_name(buf, "path_flags"); sd_write_uint32(buf, flags); } #define low_caps(X) ((u32) ((X) & 0xffffffff)) #define high_caps(X) ((u32) (((X) >> 32) & 0xffffffff)) allowed_caps = (profile->caps.allow) & ~profile->caps.deny; sd_write_uint32(buf, low_caps(allowed_caps)); sd_write_uint32(buf, low_caps(allowed_caps & profile->caps.audit)); sd_write_uint32(buf, low_caps(profile->caps.deny & profile->caps.quiet)); sd_write_uint32(buf, 0); sd_write_struct(buf, "caps64"); sd_write_uint32(buf, high_caps(allowed_caps)); sd_write_uint32(buf, high_caps(allowed_caps & profile->caps.audit)); sd_write_uint32(buf, high_caps(profile->caps.deny & profile->caps.quiet)); sd_write_uint32(buf, 0); sd_write_structend(buf); sd_serialize_rlimits(buf, &profile->rlimits); if (profile->net.allow && kernel_supports_network) { size_t i; sd_write_array(buf, "net_allowed_af", get_af_max()); for (i = 0; i < get_af_max(); i++) { u16 allowed = profile->net.allow[i] & ~profile->net.deny[i]; sd_write_uint16(buf, allowed); sd_write_uint16(buf, allowed & profile->net.audit[i]); sd_write_uint16(buf, profile->net.deny[i] & profile->net.quiet[i]); } sd_write_arrayend(buf); } else if (profile->net.allow && (warnflags & WARN_RULE_NOT_ENFORCED)) pwarn(_("profile %s network rules not enforced\n"), profile->name); if (profile->policy.dfa) { sd_write_struct(buf, "policydb"); sd_serialize_dfa(buf, profile->policy.dfa, profile->policy.size); sd_write_structend(buf); } /* either have a single dfa or lists of different entry types */ sd_serialize_dfa(buf, profile->dfa.dfa, profile->dfa.size); sd_serialize_xtable(buf, profile->exec_table); sd_write_structend(buf); } void sd_serialize_top_profile(std::ostringstream &buf, Profile *profile) { uint32_t version; version = ENCODE_VERSION(force_complain, policy_version, parser_abi_version, kernel_abi_version); sd_write_name(buf, "version"); sd_write_uint32(buf, version); if (profile->ns) { sd_write_string(buf, profile->ns, "namespace"); } sd_serialize_profile(buf, profile, profile->parent ? 1 : 0); } int __sd_serialize_profile(int option, aa_kernel_interface *kernel_interface, Profile *prof, int cache_fd) { autoclose int fd = -1; int error, size, wsize; std::ostringstream work_area; switch (option) { case OPTION_ADD: case OPTION_REPLACE: case OPTION_REMOVE: break; case OPTION_STDOUT: fd = dup(1); if (fd < 0) { error = -errno; PERROR(_("Unable to open stdout - %s\n"), strerror(errno)); goto exit; } break; case OPTION_OFILE: fd = dup(fileno(ofile)); if (fd < 0) { error = -errno; PERROR(_("Unable to open output file - %s\n"), strerror(errno)); goto exit; } break; default: error = -EINVAL; goto exit; break; } error = 0; if (option == OPTION_REMOVE) { if (kernel_load) { if (aa_kernel_interface_remove_policy(kernel_interface, prof->fqname().c_str()) == -1) error = -errno; } } else { std::string tmp; sd_serialize_top_profile(work_area, prof); tmp = work_area.str(); size = (long) work_area.tellp(); if (kernel_load) { if (option == OPTION_ADD && aa_kernel_interface_load_policy(kernel_interface, tmp.c_str(), size) == -1) { error = -errno; } else if (option == OPTION_REPLACE && aa_kernel_interface_replace_policy(kernel_interface, tmp.c_str(), size) == -1) { error = -errno; } } else if ((option == OPTION_STDOUT || option == OPTION_OFILE) && aa_kernel_interface_write_policy(fd, tmp.c_str(), size) == -1) { error = -errno; } if (cache_fd != -1) { wsize = write(cache_fd, tmp.c_str(), size); if (wsize < 0) { error = -errno; } else if (wsize < size) { PERROR(_("%s: Unable to write entire profile entry to cache\n"), progname); error = -EIO; } } } if (!prof->hat_table.empty() && option != OPTION_REMOVE) { if (load_flattened_hats(prof, option, kernel_interface, cache_fd) == 0) return 0; } exit: return error; } apparmor-2.13.3/parser/tst/0000755000175000017500000000000013502024172013313 5ustar jjjjapparmor-2.13.3/parser/tst/gen-xtrans.pl0000755000175000017500000001404413502024172015744 0ustar jjjj#!/usr/bin/perl use strict; use Locale::gettext; use POSIX; setlocale(LC_MESSAGES, ""); my $prefix="simple_tests/generated_x"; my $prefix_leading="simple_tests/generated_perms_leading"; my $prefix_safe="simple_tests/generated_perms_safe"; my @trans_types = ("p", "P", "c", "C", "u", "i"); my @modifiers = ("i", "u"); my %trans_modifiers = ( "p" => \@modifiers, "P" => \@modifiers, "c" => \@modifiers, "C" => \@modifiers, ); my @targets = ("", "target", "target2"); my @null_target = (""); my %named_trans = ( "p" => \@targets, "P" => \@targets, "c" => \@targets, "C" => \@targets, "u" => \@null_target, "i" => \@null_target, ); my %safe_map = ( "p" => "unsafe", "P" => "safe", "c" => "unsafe", "C" => "safe", "u" => "", "i" => "", ); my %invert_safe = ( "safe" => "unsafe", "unsafe" => "safe", ); # audit qualifier disabled for now it really shouldn't affect the conflict # test but it may be worth checking every once in awhile #my @qualifiers = ("", "owner", "audit", "audit owner"); my @qualifiers = ("", "owner"); my $count = 0; gen_conflicting_x(); gen_overlap_re_exact(); gen_dominate_re_re(); gen_ambiguous_re_re(); gen_leading_perms("exact", "/bin/cat", "/bin/cat"); gen_leading_perms("exact-re", "/bin/*", "/bin/*"); gen_leading_perms("overlap", "/*", "/bin/cat"); gen_leading_perms("dominate", "/**", "/*"); gen_leading_perms("ambiguous", "/a*", "/*b"); gen_safe_perms("exact", "PASS", "", "/bin/cat", "/bin/cat"); gen_safe_perms("exact-re", "PASS", "", "/bin/*", "/bin/*"); gen_safe_perms("overlap", "PASS", "", "/*", "/bin/cat"); gen_safe_perms("dominate", "PASS", "", "/**", "/*"); gen_safe_perms("ambiguous", "PASS", "", "/a*", "/*b"); gen_safe_perms("exact", "FAIL", "inv", "/bin/cat", "/bin/cat"); gen_safe_perms("exact-re", "FAIL", "inv", "/bin/*", "/bin/*"); gen_safe_perms("overlap", "PASS", "inv", "/*", "/bin/cat"); gen_safe_perms("dominate", "FAIL", "inv", "/**", "/*"); gen_safe_perms("ambiguous", "FAIL", "inv", "/a*", "/*b"); print "Generated $count xtransition interaction tests\n"; sub gen_list { my @output; foreach my $trans (@trans_types) { if ($trans_modifiers{$trans}) { foreach my $mod (@{$trans_modifiers{$trans}}) { push @output, "${trans}${mod}x"; } } push @output, "${trans}x"; } return @output; } sub print_rule($$$$$$) { my ($file, $leading, $qual, $name, $perm, $target) = @_; if ($leading) { print $file "\t${qual} ${perm} ${name}"; } else { print $file "\t${qual} ${name} ${perm}"; } if ($target ne "") { print $file " -> $target"; } print $file ",\n"; } sub gen_file($$$$$$$$$$$$) { my ($name, $xres, $leading1, $qual1, $rule1, $perm1, $target1, $leading2, $qual2, $rule2, $perm2, $target2) = @_; # print "$xres $rule1 $perm1 $target1 $rule2 $perm2 $target2\n"; my $file; unless (open $file, ">$name") { print("couldn't open $name\n"); exit 1; } print $file "#\n"; print $file "#=DESCRIPTION ${name}\n"; print $file "#=EXRESULT ${xres}\n"; print $file "#\n"; print $file "/usr/bin/foo {\n"; print_rule($file, $leading1, $qual1, $rule1, $perm1, $target1); print_rule($file, $leading2, $qual2, $rule2, $perm2, $target2); print $file "}\n"; close($file); $count++; } #NOTE: currently we don't do px to cx, or cx to px conversion # so # /foo { # /* px -> /foo//bar, # /* cx -> bar, # # will conflict # #NOTE: conflict tests don't tests leading permissions or using unsafe keywords # It is assumed that there are extra tests to verify 1 to 1 coorispondance sub gen_files($$$$) { my ($name, $rule1, $rule2, $default) = @_; my @perms = gen_list(); # print "@perms\n"; foreach my $i (@perms) { foreach my $t (@{$named_trans{substr($i, 0, 1)}}) { foreach my $q (@qualifiers) { foreach my $j (@perms) { foreach my $u (@{$named_trans{substr($j, 0, 1)}}) { foreach my $r (@qualifiers) { my $file="${prefix}/${name}-$q$i$t-$r$j$u.sd"; # print "$file\n"; #override failures when transitions are the same my $xres = ${default}; if ($i eq $j && $t eq $u) { $xres = "PASS"; } # print "foo $xres $rule1 $i $t $rule2 $j $u\n"; gen_file($file, $xres, 0, $q, $rule1, $i, $t, 0, $r, $rule2, $j, $u); } } } } } } } sub gen_conflicting_x { gen_files("conflict", "/bin/cat", "/bin/cat", "FAIL"); } sub gen_overlap_re_exact { gen_files("exact", "/bin/cat", "/bin/*", "PASS"); } # we currently don't support this, once supported change to "PASS" sub gen_dominate_re_re { gen_files("dominate", "/bin/*", "/bin/**", "FAIL"); } sub gen_ambiguous_re_re { gen_files("ambiguous", "/bin/a*", "/bin/*b", "FAIL"); } # test that rules that lead with permissions don't conflict with # the same rule using trailing permissions. sub gen_leading_perms($$$) { my ($name, $rule1, $rule2) = @_; my @perms = gen_list(); foreach my $i (@perms) { foreach my $t (@{$named_trans{substr($i, 0, 1)}}) { foreach my $q (@qualifiers) { my $file="${prefix_leading}/${name}-$q$i$t.sd"; # print "$file\n"; gen_file($file, "PASS", 0, $q, $rule1, $i, $t, 1, $q, $rule2, $i, $t); } } } } # test for rules with leading safe or unsafe keywords. # check they are equivalent to their counter part, # or if $invert that they properly conflict with their counterpart sub gen_safe_perms($$$$$) { my ($name, $xres, $invert, $rule1, $rule2) = @_; my @perms = gen_list(); foreach my $i (@perms) { foreach my $t (@{$named_trans{substr($i, 0, 1)}}) { foreach my $q (@qualifiers) { my $qual = $safe_map{substr($i, 0, 1)}; if ($invert) { $qual = $invert_safe{$qual}; } if (! $invert || $qual) { my $file="${prefix_safe}/${name}-$invert-$q${qual}-rule-$i$t.sd"; # print "$file\n"; gen_file($file, $xres, 0, "$q $qual", $rule1, $i, $t, 1, $q, $rule2, $i, $t); $file="${prefix_safe}/${name}-$invert-$q$qual${i}-rule-$t.sd"; gen_file($file, $xres, 0, $q, $rule1, $i, $t, 1, "$q $qual", $rule2, $i, $t); } } } } } apparmor-2.13.3/parser/tst/parser.conf0000644000175000017500000000000013502024172015444 0ustar jjjjapparmor-2.13.3/parser/tst/caching.py0000755000175000017500000005424313502024172015274 0ustar jjjj#!/usr/bin/env python3 # ------------------------------------------------------------------ # # Copyright (C) 2013-2015 Canonical Ltd. # Authors: Steve Beattie # Tyler Hicks # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ # TODO # - check cache not used if parser in $PATH is newer # - check cache used for force-complain, disable symlink, etc. from argparse import ArgumentParser import os import platform import shutil import time import tempfile import unittest import testlib ABSTRACTION_CONTENTS = ''' # Simple example abstraction capability setuid, ''' ABSTRACTION = 'suid-abstraction' PROFILE_CONTENTS = ''' # Simple example profile for caching tests /bin/pingy { #include <%s> capability net_raw, network inet raw, /bin/ping mixr, /etc/modules.conf r, } ''' % (ABSTRACTION) PROFILE = 'sbin.pingy' config = None class AAParserCachingCommon(testlib.AATestTemplate): do_cleanup = True def setUp(self): '''setup for each test''' global config # REPORT ALL THE OUTPUT self.maxDiff = None self.tmp_dir = tempfile.mkdtemp(prefix='aa-caching-') os.chmod(self.tmp_dir, 0o755) # write our sample abstraction and profile out self.abstraction = testlib.write_file(self.tmp_dir, ABSTRACTION, ABSTRACTION_CONTENTS) self.profile = testlib.write_file(self.tmp_dir, PROFILE, PROFILE_CONTENTS) if config.debug: self.do_cleanup = False self.debug = True # Warnings break the test harness, but chroots may not be setup # to have the config file, etc. self.cmd_prefix = [config.parser, '--config-file=./parser.conf', '--base', self.tmp_dir, '--skip-kernel-load'] if not self.is_apparmorfs_mounted(): self.cmd_prefix += ['-M', './features_files/features.all'] # Otherwise get_cache_dir() will try to create /var/cache/apparmor # and will fail when the test suite is run as non-root. self.cmd_prefix += [ '--cache-loc', os.path.join(self.tmp_dir, 'cache') ] # create directory for cached blobs # NOTE: get_cache_dir() requires cmd_prefix to be fully initialized self.cache_dir = self.get_cache_dir(create=True) # default path of the output cache file self.cache_file = os.path.join(self.cache_dir, PROFILE) def tearDown(self): '''teardown for each test''' if not self.do_cleanup: print("\n===> Skipping cleanup, leaving testfiles behind in '%s'" % (self.tmp_dir)) else: if os.path.exists(self.tmp_dir): shutil.rmtree(self.tmp_dir) def get_cache_dir(self, create=False): cmd = [config.parser, '--print-cache-dir'] + self.cmd_prefix rc, report = self.run_cmd(cmd) if rc != 0: if "unrecognized option '--print-cache-dir'" not in report: self.fail('Unknown apparmor_parser error:\n%s' % report) cache_dir = os.path.join(self.tmp_dir, 'cache') else: cache_dir = report.strip() if create: os.makedirs(cache_dir) return cache_dir def assert_path_exists(self, path, expected=True): if expected is True: self.assertTrue(os.path.exists(path), 'test did not create file %s, when it was expected to do so' % path) else: self.assertFalse(os.path.exists(path), 'test created file %s, when it was not expected to do so' % path) def is_apparmorfs_mounted(self): return os.path.exists("/sys/kernel/security/apparmor") def require_apparmorfs(self): # skip the test if apparmor securityfs isn't mounted if not self.is_apparmorfs_mounted(): raise unittest.SkipTest("WARNING: /sys/kernel/security/apparmor does not exist. Skipping test.") def compare_features_file(self, features_path, expected=True): # tests that need this function should call require_apparmorfs() early # compare features contents expected_output = testlib.read_features_dir('/sys/kernel/security/apparmor/features') with open(features_path) as f: features = f.read() if expected: self.assertEquals(expected_output, features, "features contents differ, expected:\n%s\nresult:\n%s" % (expected_output, features)) else: self.assertNotEquals(expected_output, features, "features contents equal, expected:\n%s\nresult:\n%s" % (expected_output, features)) class AAParserBasicCachingTests(AAParserCachingCommon): def setUp(self): super(AAParserBasicCachingTests, self).setUp() def test_no_cache_by_default(self): '''test profiles are not cached by default''' cmd = list(self.cmd_prefix) cmd.extend(['-q', '-r', self.profile]) self.run_cmd_check(cmd) self.assert_path_exists(os.path.join(self.cache_dir, PROFILE), expected=False) def test_no_cache_w_skip_cache(self): '''test profiles are not cached with --skip-cache''' cmd = list(self.cmd_prefix) cmd.extend(['-q', '--write-cache', '--skip-cache', '-r', self.profile]) self.run_cmd_check(cmd) self.assert_path_exists(os.path.join(self.cache_dir, PROFILE), expected=False) def test_cache_when_requested(self): '''test profiles are cached when requested''' cmd = list(self.cmd_prefix) cmd.extend(['-q', '--write-cache', '-r', self.profile]) self.run_cmd_check(cmd) self.assert_path_exists(os.path.join(self.cache_dir, PROFILE)) def test_write_features_when_caching(self): '''test features file is written when caching''' cmd = list(self.cmd_prefix) cmd.extend(['-q', '--write-cache', '-r', self.profile]) self.run_cmd_check(cmd) self.assert_path_exists(os.path.join(self.cache_dir, PROFILE)) self.assert_path_exists(os.path.join(self.cache_dir, '.features')) def test_features_match_when_caching(self): '''test features file is written when caching''' self.require_apparmorfs() cmd = list(self.cmd_prefix) cmd.extend(['-q', '--write-cache', '-r', self.profile]) self.run_cmd_check(cmd) self.assert_path_exists(os.path.join(self.cache_dir, PROFILE)) self.assert_path_exists(os.path.join(self.cache_dir, '.features')) self.compare_features_file(os.path.join(self.cache_dir, '.features')) class AAParserAltCacheBasicTests(AAParserBasicCachingTests): '''Same tests as above, but with an alternate cache location specified on the command line''' def setUp(self): super(AAParserAltCacheBasicTests, self).setUp() alt_cache_loc = tempfile.mkdtemp(prefix='aa-alt-cache', dir=self.tmp_dir) os.chmod(alt_cache_loc, 0o755) self.unused_cache_loc = self.cache_dir self.cmd_prefix.extend(['--cache-loc', alt_cache_loc]) self.cache_dir = self.get_cache_dir() def tearDown(self): if len(os.listdir(self.unused_cache_loc)) > 0: self.fail('original cache dir \'%s\' not empty' % self.unused_cache_loc) super(AAParserAltCacheBasicTests, self).tearDown() class AAParserCreateCacheBasicTestsCacheExists(AAParserBasicCachingTests): '''Same tests as above, but with create cache option on the command line and the cache already exists''' def setUp(self): super(AAParserCreateCacheBasicTestsCacheExists, self).setUp() self.cmd_prefix.append('--create-cache-dir') class AAParserCreateCacheBasicTestsCacheNotExist(AAParserBasicCachingTests): '''Same tests as above, but with create cache option on the command line and cache dir removed''' def setUp(self): super(AAParserCreateCacheBasicTestsCacheNotExist, self).setUp() shutil.rmtree(self.cache_dir) self.cmd_prefix.append('--create-cache-dir') class AAParserCreateCacheAltCacheTestsCacheNotExist(AAParserBasicCachingTests): '''Same tests as above, but with create cache option on the command line, alt cache specified, and cache dir removed''' def setUp(self): super(AAParserCreateCacheAltCacheTestsCacheNotExist, self).setUp() shutil.rmtree(self.cache_dir) self.cmd_prefix.append('--create-cache-dir') class AAParserCachingTests(AAParserCachingCommon): def setUp(self): super(AAParserCachingTests, self).setUp() r = testlib.filesystem_time_resolution() self.mtime_res = r[1] def _generate_cache_file(self): cmd = list(self.cmd_prefix) cmd.extend(['-q', '--write-cache', '-r', self.profile]) self.run_cmd_check(cmd) self.assert_path_exists(self.cache_file) def _assertTimeStampEquals(self, time1, time2): '''Compare two timestamps to ensure equality''' # python 3.2 and earlier don't support writing timestamps with # nanosecond resolution, only microsecond. When comparing # timestamps in such an environment, loosen the equality bounds # to compensate # Reference: https://bugs.python.org/issue12904 (major, minor, _) = platform.python_version_tuple() if (int(major) < 3) or ((int(major) == 3) and (int(minor) <= 2)): self.assertAlmostEquals(time1, time2, places=5) else: self.assertEquals(time1, time2) def _set_mtime(self, path, mtime): atime = os.stat(path).st_atime os.utime(path, (atime, mtime)) self._assertTimeStampEquals(os.stat(path).st_mtime, mtime) def test_cache_loaded_when_exists(self): '''test cache is loaded when it exists, is newer than profile, and features match''' self._generate_cache_file() cmd = list(self.cmd_prefix) cmd.extend(['-v', '-r', self.profile]) self.run_cmd_check(cmd, expected_string='Cached reload succeeded') def test_cache_not_loaded_when_skip_arg(self): '''test cache is not loaded when --skip-cache is passed''' self._generate_cache_file() cmd = list(self.cmd_prefix) cmd.extend(['-v', '--skip-cache', '-r', self.profile]) self.run_cmd_check(cmd, expected_string='Replacement succeeded for') def test_cache_not_loaded_when_skip_read_arg(self): '''test cache is not loaded when --skip-read-cache is passed''' self._generate_cache_file() cmd = list(self.cmd_prefix) cmd.extend(['-v', '--skip-read-cache', '-r', self.profile]) self.run_cmd_check(cmd, expected_string='Replacement succeeded for') def test_cache_not_loaded_when_features_differ(self): '''test cache is not loaded when features file differs''' self._generate_cache_file() testlib.write_file(self.cache_dir, '.features', 'monkey\n') cmd = list(self.cmd_prefix) cmd.extend(['-v', '-r', self.profile]) self.run_cmd_check(cmd, expected_string='Replacement succeeded for') def test_cache_writing_does_not_overwrite_features_when_features_differ(self): '''test cache writing does not overwrite the features files when it differs and --skip-bad-cache is given''' self.require_apparmorfs() features_file = testlib.write_file(self.cache_dir, '.features', 'monkey\n') cmd = list(self.cmd_prefix) cmd.extend(['-v', '--write-cache', '--skip-bad-cache', '-r', self.profile]) self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.assert_path_exists(features_file) # ensure that the features does *not* match the current features set self.compare_features_file(features_file, expected=False) def test_cache_writing_skipped_when_features_differ(self): '''test cache writing is skipped when features file differs''' testlib.write_file(self.cache_dir, '.features', 'monkey\n') cmd = list(self.cmd_prefix) cmd.extend(['-v', '--write-cache', '--skip-bad-cache', '-r', self.profile]) self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.assert_path_exists(self.cache_file, expected=False) def test_cache_writing_collision_of_features(self): '''test cache writing collision of features''' # cache dir with different features causes a collision resulting # in a new cache dir self.require_apparmorfs() features_file = testlib.write_file(self.cache_dir, '.features', 'monkey\n') new_file = self.get_cache_dir() new_features_file = new_file + '/.features'; cmd = list(self.cmd_prefix) cmd.extend(['-v', '--write-cache', '-r', self.profile]) self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.assert_path_exists(features_file) self.assert_path_exists(new_features_file) self.compare_features_file(new_features_file) def test_cache_writing_updates_cache_file(self): '''test cache writing updates cache file''' cache_file = testlib.write_file(self.cache_dir, PROFILE, 'monkey\n') orig_stat = os.stat(cache_file) cmd = list(self.cmd_prefix) cmd.extend(['-v', '--write-cache', '-r', self.profile]) self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.assert_path_exists(cache_file) stat = os.stat(cache_file) # We check sizes here rather than whether the string monkey is # in cache_contents because of the difficulty coercing cache # file bytes into strings in python3 self.assertNotEquals(orig_stat.st_size, stat.st_size, 'Expected cache file to be updated, size is not changed.') self.assertEquals(os.stat(self.profile).st_mtime, stat.st_mtime) def test_cache_writing_clears_all_files(self): '''test cache writing clears all cache files''' check_file = testlib.write_file(self.cache_dir, 'monkey', 'monkey\n') cmd = list(self.cmd_prefix) cmd.extend(['-v', '--write-cache', '-r', self.profile]) self.run_cmd_check(cmd, expected_string='Replacement succeeded for') self.assert_path_exists(check_file, expected=False) def test_profile_mtime_preserved(self): '''test profile mtime is preserved when it is newest''' expected = 1 self._set_mtime(self.abstraction, 0) self._set_mtime(self.profile, expected) self._generate_cache_file() self.assertEquals(expected, os.stat(self.cache_file).st_mtime) def test_abstraction_mtime_preserved(self): '''test abstraction mtime is preserved when it is newest''' expected = 1000 self._set_mtime(self.profile, 0) self._set_mtime(self.abstraction, expected) self._generate_cache_file() self.assertEquals(expected, os.stat(self.cache_file).st_mtime) def test_equal_mtimes_preserved(self): '''test equal profile and abstraction mtimes are preserved''' expected = 10000 + self.mtime_res self._set_mtime(self.profile, expected) self._set_mtime(self.abstraction, expected) self._generate_cache_file() self.assertEquals(expected, os.stat(self.cache_file).st_mtime) def test_profile_newer_skips_cache(self): '''test cache is skipped if profile is newer''' self._generate_cache_file() profile_mtime = os.stat(self.cache_file).st_mtime + self.mtime_res self._set_mtime(self.profile, profile_mtime) orig_stat = os.stat(self.cache_file) cmd = list(self.cmd_prefix) cmd.extend(['-v', '-r', self.profile]) self.run_cmd_check(cmd, expected_string='Replacement succeeded for') stat = os.stat(self.cache_file) self.assertEquals(orig_stat.st_size, stat.st_size) self.assertEquals(orig_stat.st_ino, stat.st_ino) self.assertEquals(orig_stat.st_mtime, stat.st_mtime) def test_abstraction_newer_skips_cache(self): '''test cache is skipped if abstraction is newer''' self._generate_cache_file() abstraction_mtime = os.stat(self.cache_file).st_mtime + self.mtime_res self._set_mtime(self.abstraction, abstraction_mtime) orig_stat = os.stat(self.cache_file) cmd = list(self.cmd_prefix) cmd.extend(['-v', '-r', self.profile]) self.run_cmd_check(cmd, expected_string='Replacement succeeded for') stat = os.stat(self.cache_file) self.assertEquals(orig_stat.st_size, stat.st_size) self.assertEquals(orig_stat.st_ino, stat.st_ino) self.assertEquals(orig_stat.st_mtime, stat.st_mtime) def test_profile_newer_rewrites_cache(self): '''test cache is rewritten if profile is newer''' self._generate_cache_file() profile_mtime = os.stat(self.cache_file).st_mtime + self.mtime_res self._set_mtime(self.profile, profile_mtime) orig_stat = os.stat(self.cache_file) cmd = list(self.cmd_prefix) cmd.extend(['-v', '-r', '-W', self.profile]) self.run_cmd_check(cmd, expected_string='Replacement succeeded for') stat = os.stat(self.cache_file) self.assertNotEquals(orig_stat.st_ino, stat.st_ino) self._assertTimeStampEquals(profile_mtime, stat.st_mtime) def test_abstraction_newer_rewrites_cache(self): '''test cache is rewritten if abstraction is newer''' self._generate_cache_file() abstraction_mtime = os.stat(self.cache_file).st_mtime + self.mtime_res self._set_mtime(self.abstraction, abstraction_mtime) orig_stat = os.stat(self.cache_file) cmd = list(self.cmd_prefix) cmd.extend(['-v', '-r', '-W', self.profile]) self.run_cmd_check(cmd, expected_string='Replacement succeeded for') stat = os.stat(self.cache_file) self.assertNotEquals(orig_stat.st_ino, stat.st_ino) self._assertTimeStampEquals(abstraction_mtime, stat.st_mtime) def test_parser_newer_uses_cache(self): '''test cache is not skipped if parser is newer''' self._generate_cache_file() # copy parser os.mkdir(os.path.join(self.tmp_dir, 'parser')) new_parser = os.path.join(self.tmp_dir, 'parser', 'apparmor_parser') shutil.copy(config.parser, new_parser) self._set_mtime(new_parser, os.stat(self.cache_file).st_mtime + self.mtime_res) cmd = list(self.cmd_prefix) cmd[0] = new_parser cmd.extend(['-v', '-r', self.profile]) self.run_cmd_check(cmd, expected_string='Cached reload succeeded for') def _purge_cache_test(self, location): cache_file = testlib.write_file(self.cache_dir, location, 'monkey\n') cmd = list(self.cmd_prefix) cmd.extend(['-v', '--purge-cache', '-r', self.profile]) self.run_cmd_check(cmd) # no message is output self.assert_path_exists(cache_file, expected=False) def test_cache_purge_removes_features_file(self): '''test cache --purge-cache removes .features file''' self._purge_cache_test('.features') def test_cache_purge_removes_cache_file(self): '''test cache --purge-cache removes profile cache file''' self._purge_cache_test(PROFILE) def test_cache_purge_removes_other_cache_files(self): '''test cache --purge-cache removes other cache files''' self._purge_cache_test('monkey') class AAParserAltCacheTests(AAParserCachingTests): '''Same tests as above, but with an alternate cache location specified on the command line''' check_orig_cache = True def setUp(self): super(AAParserAltCacheTests, self).setUp() alt_cache_loc = tempfile.mkdtemp(prefix='aa-alt-cache', dir=self.tmp_dir) os.chmod(alt_cache_loc, 0o755) self.orig_cache_dir = self.cache_dir self.cmd_prefix.extend(['--cache-loc', alt_cache_loc]) self.cache_dir = self.get_cache_dir(create=True) self.cache_file = os.path.join(self.cache_dir, PROFILE) def tearDown(self): if self.check_orig_cache and len(os.listdir(self.orig_cache_dir)) > 0: self.fail('original cache dir \'%s\' not empty' % self.orig_cache_dir) super(AAParserAltCacheTests, self).tearDown() def test_cache_purge_leaves_original_cache_alone(self): '''test cache purging only touches alt cache''' # skip tearDown check to ensure non-alt cache is empty self.check_orig_cache = False filelist = [PROFILE, '.features', 'monkey'] for f in filelist: testlib.write_file(self.orig_cache_dir, f, 'monkey\n') self._purge_cache_test(PROFILE) for f in filelist: if not os.path.exists(os.path.join(self.orig_cache_dir, f)): self.fail('cache purge removed %s, was not supposed to' % (os.path.join(self.orig_cache_dir, f))) def main(): global config p = ArgumentParser() p.add_argument('-p', '--parser', default=testlib.DEFAULT_PARSER, action="store", dest='parser') p.add_argument('-v', '--verbose', action="store_true", dest="verbose") p.add_argument('-d', '--debug', action="store_true", dest="debug") config = p.parse_args() verbosity = 1 if config.verbose: verbosity = 2 test_suite = unittest.TestSuite() test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AAParserBasicCachingTests)) test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AAParserAltCacheBasicTests)) test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AAParserCreateCacheBasicTestsCacheExists)) test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AAParserCreateCacheBasicTestsCacheNotExist)) test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AAParserCreateCacheAltCacheTestsCacheNotExist)) test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AAParserCachingTests)) test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AAParserAltCacheTests)) rc = 0 try: result = unittest.TextTestRunner(verbosity=verbosity).run(test_suite) if not result.wasSuccessful(): rc = 1 except: rc = 1 return rc if __name__ == "__main__": rc = main() exit(rc) apparmor-2.13.3/parser/tst/equality.sh0000755000175000017500000005323213502024172015514 0ustar jjjj#!/bin/bash # # Copyright (c) 2013 # Canonical, Ltd. (All rights reserved) # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Canonical Ltd. # # Tests for post-parser equality among multiple profiles. These tests are # useful to verify that keyword aliases, formatting differences, etc., all # result in the same parser output. set -o pipefail _SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}" ) APPARMOR_PARSER="${APPARMOR_PARSER:-${_SCRIPTDIR}/../apparmor_parser}" fails=0 errors=0 verbose="${VERBOSE:-}" hash_binary_policy() { printf %s "$1" | ${APPARMOR_PARSER} --features-file ${_SCRIPTDIR}/features_files/features.all -qS 2>/dev/null| md5sum | cut -d ' ' -f 1 return $? } # verify_binary - compares the binary policy of multiple profiles # $1: Test type (equality or inequality) # $2: A short description of the test # $3: The known-good profile # $4..$n: The profiles to compare against $3 # # Upon failure/error, prints out the test description and profiles that failed # and increments $fails or $errors for each failure and error, respectively verify_binary() { local t=$1 local desc=$2 local good_profile=$3 local good_hash local ret=0 shift shift shift if [ "$t" != "equality" ] && [ "$t" != "inequality" ] then printf "\nERROR: Unknown test mode:\n%s\n\n" "$t" 1>&2 ((errors++)) return $((ret + 1)) fi if [ -n "$verbose" ] ; then printf "Binary %s %s" "$t" "$desc" ; fi good_hash=$(hash_binary_policy "$good_profile") if [ $? -ne 0 ] then if [ -z "$verbose" ] ; then printf "Binary %s %s" "$t" "$desc" ; fi printf "\nERROR: Error hashing the following \"known-good\" profile:\n%s\n\n" \ "$good_profile" 1>&2 ((errors++)) return $((ret + 1)) fi for profile in "$@" do hash=$(hash_binary_policy "$profile") if [ $? -ne 0 ] then if [ -z "$verbose" ] ; then printf "Binary %s %s" "$t" "$desc" ; fi printf "\nERROR: Error hashing the following profile:\n%s\n\n" \ "$profile" 1>&2 ((errors++)) ((ret++)) elif [ "$t" == "equality" ] && [ "$hash" != "$good_hash" ] then if [ -z "$verbose" ] ; then printf "Binary %s %s" "$t" "$desc" ; fi printf "\nFAIL: Hash values do not match\n" 2>&1 printf "known-good (%s) != profile-under-test (%s) for the following profile:\n%s\n\n" \ "$good_hash" "$hash" "$profile" 1>&2 ((fails++)) ((ret++)) elif [ "$t" == "inequality" ] && [ "$hash" == "$good_hash" ] then if [ -z "$verbose" ] ; then printf "Binary %s %s" "$t" "$desc" ; fi printf "\nFAIL: Hash values match\n" 2>&1 printf "known-good (%s) == profile-under-test (%s) for the following profile:\n%s\n\n" \ "$good_hash" "$hash" "$profile" 1>&2 ((fails++)) ((ret++)) fi done if [ $ret -eq 0 ] then if [ -z "$verbose" ] ; then printf "." else printf " ok\n" fi fi return $ret } verify_binary_equality() { verify_binary "equality" "$@" } verify_binary_inequality() { verify_binary "inequality" "$@" } printf "Equality Tests:\n" verify_binary_equality "dbus send" \ "/t { dbus send, }" \ "/t { dbus write, }" \ "/t { dbus w, }" verify_binary_equality "dbus receive" \ "/t { dbus receive, }" \ "/t { dbus read, }" \ "/t { dbus r, }" verify_binary_equality "dbus send + receive" \ "/t { dbus (send, receive), }" \ "/t { dbus (read, write), }" \ "/t { dbus (r, w), }" \ "/t { dbus (rw), }" \ "/t { dbus rw, }" \ verify_binary_equality "dbus all accesses" \ "/t { dbus (send, receive, bind, eavesdrop), }" \ "/t { dbus (read, write, bind, eavesdrop), }" \ "/t { dbus (r, w, bind, eavesdrop), }" \ "/t { dbus (rw, bind, eavesdrop), }" \ "/t { dbus (), }" \ "/t { dbus, }" \ verify_binary_equality "dbus implied accesses with a bus conditional" \ "/t { dbus (send, receive, bind, eavesdrop) bus=session, }" \ "/t { dbus (read, write, bind, eavesdrop) bus=session, }" \ "/t { dbus (r, w, bind, eavesdrop) bus=session, }" \ "/t { dbus (rw, bind, eavesdrop) bus=session, }" \ "/t { dbus () bus=session, }" \ "/t { dbus bus=session, }" \ verify_binary_equality "dbus implied accesses for services" \ "/t { dbus bind name=com.foo, }" \ "/t { dbus name=com.foo, }" verify_binary_equality "dbus implied accesses for messages" \ "/t { dbus (send, receive) path=/com/foo interface=org.foo, }" \ "/t { dbus path=/com/foo interface=org.foo, }" verify_binary_equality "dbus implied accesses for messages with peer names" \ "/t { dbus (send, receive) path=/com/foo interface=org.foo peer=(name=com.foo), }" \ "/t { dbus path=/com/foo interface=org.foo peer=(name=com.foo), }" \ "/t { dbus (send, receive) path=/com/foo interface=org.foo peer=(name=(com.foo)), }" \ "/t { dbus path=/com/foo interface=org.foo peer=(name=(com.foo)), }" verify_binary_equality "dbus implied accesses for messages with peer labels" \ "/t { dbus (send, receive) path=/com/foo interface=org.foo peer=(label=/usr/bin/app), }" \ "/t { dbus path=/com/foo interface=org.foo peer=(label=/usr/bin/app), }" verify_binary_equality "dbus element parsing" \ "/t { dbus bus=b path=/ interface=i member=m peer=(name=n label=l), }" \ "/t { dbus bus=\"b\" path=\"/\" interface=\"i\" member=\"m\" peer=(name=\"n\" label=\"l\"), }" \ "/t { dbus bus=(b) path=(/) interface=(i) member=(m) peer=(name=(n) label=(l)), }" \ "/t { dbus bus=(\"b\") path=(\"/\") interface=(\"i\") member=(\"m\") peer=(name=(\"n\") label=(\"l\")), }" \ "/t { dbus bus =b path =/ interface =i member =m peer =(name =n label =l), }" \ "/t { dbus bus= b path= / interface= i member= m peer= (name= n label= l), }" \ "/t { dbus bus = b path = / interface = i member = m peer = ( name = n label = l ), }" verify_binary_equality "dbus access parsing" \ "/t { dbus, }" \ "/t { dbus (), }" \ "/t { dbus (send, receive, bind, eavesdrop), }" \ "/t { dbus (send receive bind eavesdrop), }" \ "/t { dbus (send, receive bind, eavesdrop), }" \ "/t { dbus (send,receive,bind,eavesdrop), }" \ "/t { dbus (send,receive,,,,,,,,,,,,,,,,bind,eavesdrop), }" \ "/t { dbus (send,send,send,send send receive,bind eavesdrop), }" \ verify_binary_equality "dbus variable expansion" \ "/t { dbus (send, receive) path=/com/foo member=spork interface=org.foo peer=(name=com.foo label=/com/foo), }" \ "@{FOO}=foo /t { dbus (send, receive) path=/com/@{FOO} member=spork interface=org.@{FOO} peer=(name=com.@{FOO} label=/com/@{FOO}), }" \ "@{FOO}=foo @{SPORK}=spork /t { dbus (send, receive) path=/com/@{FOO} member=@{SPORK} interface=org.@{FOO} peer=(name=com.@{FOO} label=/com/@{FOO}), }" \ "@{FOO}=/com/foo /t { dbus (send, receive) path=@{FOO} member=spork interface=org.foo peer=(name=com.foo label=@{FOO}), }" \ "@{FOO}=com /t { dbus (send, receive) path=/@{FOO}/foo member=spork interface=org.foo peer=(name=@{FOO}.foo label=/@{FOO}/foo), }" verify_binary_equality "dbus variable expansion, multiple values/rules" \ "/t { dbus (send, receive) path=/com/foo, dbus (send, receive) path=/com/bar, }" \ "/t { dbus (send, receive) path=/com/{foo,bar}, }" \ "/t { dbus (send, receive) path={/com/foo,/com/bar}, }" \ "@{FOO}=foo /t { dbus (send, receive) path=/com/@{FOO}, dbus (send, receive) path=/com/bar, }" \ "@{FOO}=foo bar /t { dbus (send, receive) path=/com/@{FOO}, }" \ "@{FOO}=bar foo /t { dbus (send, receive) path=/com/@{FOO}, }" \ "@{FOO}={bar,foo} /t { dbus (send, receive) path=/com/@{FOO}, }" \ "@{FOO}=foo @{BAR}=bar /t { dbus (send, receive) path=/com/{@{FOO},@{BAR}}, }" \ verify_binary_equality "dbus variable expansion, ensure rule de-duping occurs" \ "/t { dbus (send, receive) path=/com/foo, dbus (send, receive) path=/com/bar, }" \ "/t { dbus (send, receive) path=/com/foo, dbus (send, receive) path=/com/bar, dbus (send, receive) path=/com/bar, }" \ "@{FOO}=bar foo bar foo /t { dbus (send, receive) path=/com/@{FOO}, }" \ "@{FOO}=bar foo bar foo /t { dbus (send, receive) path=/com/@{FOO}, dbus (send, receive) path=/com/@{FOO}, }" verify_binary_equality "dbus minimization with all perms" \ "/t { dbus, }" \ "/t { dbus bus=session, dbus, }" \ "/t { dbus (send, receive, bind, eavesdrop), dbus, }" verify_binary_equality "dbus minimization with bind" \ "/t { dbus bind, }" \ "/t { dbus bind bus=session, dbus bind, }" \ "/t { dbus bind bus=system name=com.foo, dbus bind, }" verify_binary_equality "dbus minimization with send and a bus conditional" \ "/t { dbus send bus=system, }" \ "/t { dbus send bus=system path=/com/foo interface=com.foo member=bar, dbus send bus=system, }" \ "/t { dbus send bus=system peer=(label=/usr/bin/foo), dbus send bus=system, }" verify_binary_equality "dbus minimization with an audit modifier" \ "/t { audit dbus eavesdrop, }" \ "/t { audit dbus eavesdrop bus=session, audit dbus eavesdrop, }" verify_binary_equality "dbus minimization with a deny modifier" \ "/t { deny dbus send bus=system peer=(name=com.foo), }" \ "/t { deny dbus send bus=system peer=(name=com.foo label=/usr/bin/foo), deny dbus send bus=system peer=(name=com.foo), }" \ verify_binary_equality "dbus minimization found in dbus abstractions" \ "/t { dbus send bus=session, }" \ "/t { dbus send bus=session path=/org/freedesktop/DBus interface=org.freedesktop.DBus member={Hello,AddMatch,RemoveMatch,GetNameOwner,NameHasOwner,StartServiceByName} peer=(name=org.freedesktop.DBus), dbus send bus=session, }" # Rules compatible with audit, deny, and audit deny # note: change_profile does not support audit/allow/deny atm for rule in "capability" "capability mac_admin" \ "network" "network tcp" "network inet6 tcp"\ "mount" "mount /a" "mount /a -> /b" "mount options in (ro) /a -> b" \ "remount" "remount /a" \ "umount" "umount /a" \ "pivot_root" "pivot_root /a" "pivot_root oldroot=/" \ "pivot_root oldroot=/ /a" "pivot_root oldroot=/ /a -> foo" \ "ptrace" "ptrace trace" "ptrace (readby,tracedby) peer=unconfined" \ "signal" "signal (send,receive)" "signal peer=unconfined" \ "signal receive set=(kill)" \ "dbus" "dbus send" "dbus bus=system" "dbus bind name=foo" \ "dbus peer=(label=foo)" "dbus eavesdrop" \ "unix" "unix (create, listen, accept)" "unix addr=@*" "unix addr=none" \ "unix peer=(label=foo)" \ "/f r" "/f w" "/f rwmlk" "/** r" "/**/ w" \ "file /f r" "file /f w" "file /f rwmlk" \ "link /a -> /b" "link subset /a -> /b" \ "l /a -> /b" "l subset /a -> /b" \ "file l /a -> /b" "l subset /a -> /b" do verify_binary_equality "allow modifier for \"${rule}\"" \ "/t { ${rule}, }" \ "/t { allow ${rule}, }" verify_binary_equality "audit allow modifier for \"${rule}\"" \ "/t { audit ${rule}, }" \ "/t { audit allow ${rule}, }" verify_binary_inequality "audit, deny, and audit deny modifiers for \"${rule}\"" \ "/t { ${rule}, }" \ "/t { audit ${rule}, }" \ "/t { audit allow ${rule}, }" \ "/t { deny ${rule}, }" \ "/t { audit deny ${rule}, }" verify_binary_inequality "audit vs deny and audit deny modifiers for \"${rule}\"" \ "/t { audit ${rule}, }" \ "/t { deny ${rule}, }" \ "/t { audit deny ${rule}, }" verify_binary_inequality "deny and audit deny modifiers for \"${rule}\"" \ "/t { deny ${rule}, }" \ "/t { audit deny ${rule}, }" done # Rules that need special treatment for the deny modifier for rule in "/f ux" "/f Ux" "/f px" "/f Px" "/f cx" "/f Cx" "/f ix" \ "/f pux" "/f Pux" "/f pix" "/f Pix" \ "/f cux" "/f Cux" "/f cix" "/f Cix" \ "/* ux" "/* Ux" "/* px" "/* Px" "/* cx" "/* Cx" "/* ix" \ "/* pux" "/* Pux" "/* pix" "/* Pix" \ "/* cux" "/* Cux" "/* cix" "/* Cix" \ "/f px -> b " "/f Px -> b" "/f cx -> b" "/f Cx -> b" \ "/f pux -> b" "/f Pux -> b" "/f pix -> b" "/f Pix -> b" \ "/f cux -> b" "/f Cux -> b" "/f cix -> b" "/f Cix -> b" \ "/* px -> b" "/* Px -> b" "/* cx -> b" "/* Cx -> b" \ "/* pux -> b" "/* Pux -> b" "/* pix -> b" "/* Pix -> b" \ "/* cux -> b" "/* Cux -> b" "/* cix -> b" "/* Cix -> b" \ "file /f ux" "file /f Ux" "file /f px" "file /f Px" \ "file /f cx" "file /f Cx" "file /f ix" \ "file /f pux" "file /f Pux" "file /f pix" "file /f Pix" \ "/f cux" "/f Cux" "/f cix" "/f Cix" \ "file /* ux" "file /* Ux" "file /* px" "file /* Px" \ "file /* cx" "file /* Cx" "file /* ix" \ "file /* pux" "file /* Pux" "file /* pix" "file /* Pix" \ "file /* cux" "file /* Cux" "file /* cix" "file /* Cix" \ "file /f px -> b " "file /f Px -> b" "file /f cx -> b" "file /f Cx -> b" \ "file /f pux -> b" "file /f Pux -> b" "file /f pix -> b" "file /f Pix -> b" \ "file /f cux -> b" "file /f Cux -> b" "file /f cix -> b" "file /f Cix -> b" \ "file /* px -> b" "file /* Px -> b" "file /* cx -> b" "file /* Cx -> b" \ "file /* pux -> b" "file /* Pux -> b" "file /* pix -> b" "file /* Pix -> b" \ "file /* cux -> b" "file /* Cux -> b" "file /* cix -> b" "file /* Cix -> b" do verify_binary_equality "allow modifier for \"${rule}\"" \ "/t { ${rule}, }" \ "/t { allow ${rule}, }" verify_binary_equality "audit allow modifier for \"${rule}\"" \ "/t { audit ${rule}, }" \ "/t { audit allow ${rule}, }" # skip rules that don't end with x perm if [ -n "${rule##*x}" ] ; then continue ; fi verify_binary_inequality "deny, audit deny modifier for \"${rule}\"" \ "/t { ${rule}, }" \ "/t { audit ${rule}, }" \ "/t { audit allow ${rule}, }" \ "/t { deny ${rule% *} x, }" \ "/t { audit deny ${rule% *} x, }" verify_binary_inequality "audit vs deny and audit deny modifiers for \"${rule}\"" \ "/t { audit ${rule}, }" \ "/t { deny ${rule% *} x, }" \ "/t { audit deny ${rule% *} x, }" done # verify deny and audit deny differ for x perms for prefix in "/f" "/*" "file /f" "file /*" ; do verify_binary_inequality "deny and audit deny x modifiers for \"${prefix}\"" \ "/t { deny ${prefix} x, }" \ "/t { audit deny ${prefix} x, }" done #Test equality of leading and trailing file permissions for audit in "" "audit" ; do for allow in "" "allow" "deny" ; do for owner in "" "owner" ; do for f in "" "file" ; do prefix="$audit $allow $owner $f" for perm in "r" "w" "a" "l" "k" "m" "rw" "ra" \ "rl" "rk" "rm" "wl" "wk" "wm" \ "rwl" "rwk" "rwm" "ral" "rak" \ "ram" "rlk" "rlm" "rkm" "wlk" \ "wlm" "wkm" "alk" "alm" "akm" \ "lkm" "rwlk" "rwlm" "rwkm" \ "ralk" "ralm" "wlkm" "alkm" \ "rwlkm" "ralkm" ; do verify_binary_equality "leading and trailing perms for \"${perm}\"" \ "/t { ${prefix} /f ${perm}, }" \ "/t { ${prefix} ${perm} /f, }" done if [ "$allow" == "deny" ] ; then continue ; fi for perm in "ux" "Ux" "px" "Px" "cx" "Cx" \ "ix" "pux" "Pux" "pix" "Pix" \ "cux" "Cux" "cix" "Cix" do verify_binary_equality "leading and trailing perms for \"${perm}\"" \ "/t { ${prefix} /f ${perm}, }" \ "/t { ${prefix} ${perm} /f, }" done for perm in "px" "Px" "cx" "Cx" \ "pux" "Pux" "pix" "Pix" \ "cux" "Cux" "cix" "Cix" do verify_binary_equality "leading and trailing perms for x-transition \"${perm}\"" \ "/t { ${prefix} /f ${perm} -> b, }" \ "/t { ${prefix} ${perm} /f -> b, }" done done done done done #Test rule overlap for x most specific match for perm1 in "ux" "Ux" "px" "Px" "cx" "Cx" "ix" "pux" "Pux" \ "pix" "Pix" "cux" "Cux" "cix" "Cix" "px -> b" \ "Px -> b" "cx -> b" "Cx -> b" "pux -> b" "Pux ->b" \ "pix -> b" "Pix -> b" "cux -> b" "Cux -> b" \ "cix -> b" "Cix -> b" do for perm2 in "ux" "Ux" "px" "Px" "cx" "Cx" "ix" "pux" "Pux" \ "pix" "Pix" "cux" "Cux" "cix" "Cix" "px -> b" \ "Px -> b" "cx -> b" "Cx -> b" "pux -> b" "Pux ->b" \ "pix -> b" "Pix -> b" "cux -> b" "Cux -> b" \ "cix -> b" "Cix -> b" do if [ "$perm1" == "$perm2" ] ; then verify_binary_equality "Exec perm \"${perm1}\" - most specific match: same as glob" \ "/t { /* ${perm1}, /f ${perm2}, }" \ "/t { /* ${perm1}, }" else verify_binary_inequality "Exec \"${perm1}\" vs \"${perm2}\" - most specific match: different from glob" \ "/t { /* ${perm1}, /f ${perm2}, }" \ "/t { /* ${perm1}, }" fi done verify_binary_inequality "Exec \"${perm1}\" vs deny x - most specific match: different from glob" \ "/t { /* ${perm1}, audit deny /f x, }" \ "/t { /* ${perm1}, }" done #Test deny carves out permission verify_binary_inequality "Deny removes r perm" \ "/t { /foo/[abc] r, audit deny /foo/b r, }" \ "/t { /foo/[abc] r, }" verify_binary_equality "Deny removes r perm" \ "/t { /foo/[abc] r, audit deny /foo/b r, }" \ "/t { /foo/[ac] r, }" #this one may not be true in the future depending on if the compiled profile #is explicitly including deny permissions for dynamic composition verify_binary_equality "Deny of ungranted perm" \ "/t { /foo/[abc] r, audit deny /foo/b w, }" \ "/t { /foo/[abc] r, }" verify_binary_equality "change_profile == change_profile -> **" \ "/t { change_profile, }" \ "/t { change_profile -> **, }" verify_binary_equality "change_profile /** == change_profile /** -> **" \ "/t { change_profile /**, }" \ "/t { change_profile /** -> **, }" verify_binary_equality "change_profile /** == change_profile /** -> **" \ "/t { change_profile unsafe /**, }" \ "/t { change_profile unsafe /** -> **, }" verify_binary_equality "change_profile /** == change_profile /** -> **" \ "/t { change_profile /**, }" \ "/t { change_profile safe /** -> **, }" verify_binary_inequality "change_profile /** == change_profile /** -> **" \ "/t { change_profile /**, }" \ "/t { change_profile unsafe /**, }" verify_binary_equality "profile name is hname in rule" \ ":ns:/hname { signal peer=/hname, }" \ ":ns:/hname { signal peer=@{profile_name}, }" verify_binary_inequality "profile name is NOT fq name in rule" \ ":ns:/hname { signal peer=:ns:/hname, }" \ ":ns:/hname { signal peer=@{profile_name}, }" verify_binary_equality "profile name is hname in sub pofile rule" \ ":ns:/hname { profile child { signal peer=/hname//child, } }" \ ":ns:/hname { profile child { signal peer=@{profile_name}, } }" verify_binary_inequality "profile name is NOT fq name in sub profile rule" \ ":ns:/hname { profile child { signal peer=:ns:/hname//child, } }" \ ":ns:/hname { profile child { signal peer=@{profile_name}, } }" verify_binary_equality "profile name is hname in hat rule" \ ":ns:/hname { ^child { signal peer=/hname//child, } }" \ ":ns:/hname { ^child { signal peer=@{profile_name}, } }" verify_binary_inequality "profile name is NOT fq name in hat rule" \ ":ns:/hname { ^child { signal peer=:ns:/hname//child, } }" \ ":ns:/hname { ^child { signal peer=@{profile_name}, } }" verify_binary_equality "@{profile_name} is literal in peer" \ "/{a,b} { signal peer=/\{a,b\}, }" \ "/{a,b} { signal peer=@{profile_name}, }" verify_binary_equality "@{profile_name} is literal in peer with pattern" \ "/{a,b} { signal peer={/\{a,b\},c}, }" \ "/{a,b} { signal peer={@{profile_name},c}, }" verify_binary_inequality "@{profile_name} is not pattern in peer" \ "/{a,b} { signal peer=/{a,b}, }" \ "/{a,b} { signal peer=@{profile_name}, }" verify_binary_equality "@{profile_name} is literal in peer with esc sequence" \ "/\\\\a { signal peer=/\\\\a, }" \ "/\\\\a { signal peer=@{profile_name}, }" verify_binary_equality "@{profile_name} is literal in peer with esc alt sequence" \ "/\\{a,b\\},c { signal peer=/\\{a,b\\},c, }" \ "/\\{a,b\\},c { signal peer=@{profile_name}, }" # verify rlimit data conversions verify_binary_equality "set rlimit rttime <= 12 weeks" \ "/t { set rlimit rttime <= 12 weeks, }" \ "/t { set rlimit rttime <= $((12 * 7)) days, }" \ "/t { set rlimit rttime <= $((12 * 7 * 24)) hours, }" \ "/t { set rlimit rttime <= $((12 * 7 * 24 * 60)) minutes, }" \ "/t { set rlimit rttime <= $((12 * 7 * 24 * 60 * 60)) seconds, }" \ "/t { set rlimit rttime <= $((12 * 7 * 24 * 60 * 60 * 1000)) ms, }" \ "/t { set rlimit rttime <= $((12 * 7 * 24 * 60 * 60 * 1000 * 1000)) us, }" \ "/t { set rlimit rttime <= $((12 * 7 * 24 * 60 * 60 * 1000 * 1000)), }" verify_binary_equality "set rlimit cpu <= 42 weeks" \ "/t { set rlimit cpu <= 42 weeks, }" \ "/t { set rlimit cpu <= $((42 * 7)) days, }" \ "/t { set rlimit cpu <= $((42 * 7 * 24)) hours, }" \ "/t { set rlimit cpu <= $((42 * 7 * 24 * 60)) minutes, }" \ "/t { set rlimit cpu <= $((42 * 7 * 24 * 60 * 60)) seconds, }" \ "/t { set rlimit cpu <= $((42 * 7 * 24 * 60 * 60)), }" verify_binary_equality "set rlimit memlock <= 2GB" \ "/t { set rlimit memlock <= 2GB, }" \ "/t { set rlimit memlock <= $((2 * 1024)) MB, }" \ "/t { set rlimit memlock <= $((2 * 1024 * 1024)) KB, }" \ "/t { set rlimit memlock <= $((2 * 1024 * 1024 * 1024)) , }" \ if [ $fails -ne 0 -o $errors -ne 0 ] then printf "ERRORS: %d\nFAILS: %d\n" $errors $fails 2>&1 exit $(($fails + $errors)) fi [ -z "${verbose}" ] && printf "\n" printf "PASS\n" exit 0 apparmor-2.13.3/parser/tst/caching.profile0000644000175000017500000000024413502024172016271 0ustar jjjj# Simple example profile for caching tests /bin/pingy { capability net_raw, capability setuid, network inet raw, /bin/ping mixr, /etc/modules.conf r, } apparmor-2.13.3/parser/tst/uservars.conf0000644000175000017500000000041413502024172016033 0ustar jjjj# # Simple configuration file for the parser regression tests # config items are 'name = value' pairs. Currently the only config items # are the location of the parser and the location of the simple profiles. # parser = ../apparmor_parser profiledir = ./simple_tests/ apparmor-2.13.3/parser/tst/features_files/0000755000175000017500000000000013502024172016313 5ustar jjjjapparmor-2.13.3/parser/tst/features_files/features.dbus0000644000175000017500000000205113502024172021006 0ustar jjjjdbus {mask {acquire send receive } } caps {mask {chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap mac_override mac_admin syslog wake_alarm block_suspend } } rlimit {mask {cpu fsize data stack core rss nproc nofile memlock as locks sigpending msgqueue nice rtprio rttime } } capability {0xffffff } namespaces {pivot_root {yes } profile {yes } } network {af_mask {unspec unix local inet ax25 ipx appletalk netrom bridge atmpvc x25 inet6 rose netbeui security key netlink packet ash econet atmsvc rds sna irda pppox wanpipe llc ib can tipc bluetooth iucv rxrpc isdn phonet ieee802154 caif alg nfc vsock max } } file {mask {create read write exec append mmap_exec link lock } } domain {change_profile {yes } change_onexec {yes } change_hatv {yes } change_hat {yes } } policy {set_load {yes } } apparmor-2.13.3/parser/tst/features_files/features.mount+dbus0000644000175000017500000000210713502024172022146 0ustar jjjjdbus {mask {acquire send receive } } caps {mask {chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap mac_override mac_admin syslog wake_alarm block_suspend } } rlimit {mask {cpu fsize data stack core rss nproc nofile memlock as locks sigpending msgqueue nice rtprio rttime } } capability {0xffffff } namespaces {pivot_root {yes } profile {yes } } mount {mask {mount umount } } network {af_mask {unspec unix local inet ax25 ipx appletalk netrom bridge atmpvc x25 inet6 rose netbeui security key netlink packet ash econet atmsvc rds sna irda pppox wanpipe llc ib can tipc bluetooth iucv rxrpc isdn phonet ieee802154 caif alg nfc vsock max } } file {mask {create read write exec append mmap_exec link lock } } domain {change_profile {yes } change_onexec {yes } change_hatv {yes } change_hat {yes } } policy {set_load {yes } } apparmor-2.13.3/parser/tst/features_files/features.mount0000644000175000017500000000204213502024172021213 0ustar jjjjcaps {mask {chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap mac_override mac_admin syslog wake_alarm block_suspend } } rlimit {mask {cpu fsize data stack core rss nproc nofile memlock as locks sigpending msgqueue nice rtprio rttime } } capability {0xffffff } namespaces {pivot_root {yes } profile {yes } } mount {mask {mount umount } } network {af_mask {unspec unix local inet ax25 ipx appletalk netrom bridge atmpvc x25 inet6 rose netbeui security key netlink packet ash econet atmsvc rds sna irda pppox wanpipe llc ib can tipc bluetooth iucv rxrpc isdn phonet ieee802154 caif alg nfc vsock max } } file {mask {create read write exec append mmap_exec link lock } } domain {change_profile {yes } change_onexec {yes } change_hatv {yes } change_hat {yes } } policy {set_load {yes } } apparmor-2.13.3/parser/tst/features_files/features.all0000644000175000017500000000254113502024172020625 0ustar jjjjdbus {mask {acquire send receive } } signal {mask {hup int quit ill trap abrt bus fpe kill usr1 segv usr2 pipe alrm term stkflt chld cont stop stp ttin ttou urg xcpu xfsz vtalrm prof winch io pwr sys emt lost } } ptrace {mask {read trace } } caps {mask {chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap mac_override mac_admin syslog wake_alarm block_suspend audit_read } } rlimit {mask {cpu fsize data stack core rss nproc nofile memlock as locks sigpending msgqueue nice rtprio rttime } } capability {0xffffff } namespaces {pivot_root {yes } profile {yes } } mount {mask {mount umount } } network {af_unix {yes } af_mask {unspec unix inet ax25 ipx appletalk netrom bridge atmpvc x25 inet6 rose netbeui security key netlink packet ash econet atmsvc rds sna irda pppox wanpipe llc ib mpls can tipc bluetooth iucv rxrpc isdn phonet ieee802154 caif alg nfc vsock } } file {mask {create read write exec append mmap_exec link lock } } domain {stack {yes } change_profile {yes } change_onexec {yes } change_hatv {yes } change_hat {yes } } policy {set_load {yes } versions {v7 {yes } v6 {yes } v5 {yes } } } apparmor-2.13.3/parser/tst/features_files/features.nopolicydb0000644000175000017500000000200413502024172022211 0ustar jjjjcaps {mask {chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap mac_override mac_admin syslog wake_alarm block_suspend } } rlimit {mask {cpu fsize data stack core rss nproc nofile memlock as locks sigpending msgqueue nice rtprio rttime } } capability {0xffffff } namespaces {pivot_root {yes } profile {yes } } network {af_mask {unspec unix local inet ax25 ipx appletalk netrom bridge atmpvc x25 inet6 rose netbeui security key netlink packet ash econet atmsvc rds sna irda pppox wanpipe llc ib can tipc bluetooth iucv rxrpc isdn phonet ieee802154 caif alg nfc vsock max } } file {mask {create read write exec append mmap_exec link lock } } domain {change_profile {yes } change_onexec {yes } change_hatv {yes } change_hat {yes } } policy {set_load {yes } } apparmor-2.13.3/parser/tst/simple.pl0000755000175000017500000001024413502024172015145 0ustar jjjj#!/usr/bin/perl -w # # A simple driver for testing the subdomain parser. # All files in $CWD named *.sd will be tested against the parser. # use strict; use Getopt::Long; use Test::More; my %config; $config{'parser'} = "/sbin/apparmor_parser"; $config{'profiledir'} = "./simple_tests/"; $config{'timeout'} = 480; # in seconds my $help; my $pwd = `pwd`; chomp($pwd); GetOptions( "help|h" => \$help, ); sub usage { print STDERR "Usage $0 profile_directory\n"; print STDERR "\tTests the subdomain parser on the given profile directory\n"; print STDOUT "Bail out! Got the usage statement\n"; exit 0; } &usage if ($help); read_config(); # let environment variable override config file, for use in automated # test suites if ($ENV{APPARMOR_PARSER}) { $config{'parser'} = $ENV{APPARMOR_PARSER}; } # Override config file profile location when passed on command line if (@ARGV >= 1) { $config{'profiledir'} = shift; } if ($config{'profiledir'} =~ /^\//) { $config{'includedir'} = $config{'profiledir'}; } else { $config{'includedir'} = "$pwd/$config{'profiledir'}"; } sub read_config { my $which; if(open(CONF, "uservars.conf")) { while() { chomp; next if /^\s*#/; if (m/^\s*(\S+)\s*=\s*(.+)\s*$/) { my ($key, $value) = ($1, $2); $config{$key} = $value; } } close(CONF); } } sub test_profile { my $profile = shift; my $description = "no description for testcase"; my $expass = 1; my $istodo = 0; my $isdisabled = 0; my $result = 1; my $signal = 0; my $coredump = 0; my $child; $child = open(PARSER, "|-"); if ($child == 0) { # child open(STDOUT, ">/dev/null") or die "Failed to redirect STDOUT"; open(STDERR, ">/dev/null") or die "Failed to redirect STDERR"; exec("$config{'parser'}", "--config-file=./parser.conf", "-M", "features_files/features.all", "-S", "-I", "$config{'includedir'}") or die "Bail out! couldn't open parser"; # noreturn } # parent eval { local $SIG{ALRM} = sub { kill PIPE => $child; $description = "$description - TESTCASE TIMED OUT"; }; alarm $config{'timeout'}; open(PROFILE, $profile) or die "Bail out! couldn't open profile $profile"; while () { if (/^#=DESCRIPTION\s*(.*)/i) { $description = $1; } elsif (/^#=EXRESULT\s*(\w+)/) { if ($1 eq "PASS") { $expass = 1; } elsif ($1 eq "FAIL") { $expass = 0; } else { die "Bail out! unknown expected result '$1' in $profile"; } } elsif (/^#=TODO\s*/) { $istodo = 1; } elsif (/^#=DISABLED\s*/) { $isdisabled = 1; } else { print PARSER if not $isdisabled; } } close(PARSER) or ($! and die "Bail out! couldn't close parser pipe"); $result = $? >> 8; $signal = $? & 127; $coredump = $signal ? $? & 128 : 0; alarm 0; }; alarm 0; if ($isdisabled) { TODO: { local $TODO = "Disabled testcase."; ok(0, "TODO: $profile: $description"); } } elsif ($coredump) { ok(0, "$profile: Produced core dump (signal $signal): $description"); } elsif ($istodo) { if ($expass != $result) { fail("TODO passed unexpectedly: $profile: $description"); } else { TODO: { local $TODO = "Unfixed testcase."; ok($expass ? !$result : $result, "TODO: $profile: $description"); } } } else { ok($expass ? !$result : $result, "$profile: $description"); } } sub find_all_tests { my $testdir = shift; opendir(DIR, $testdir) or die "Bail out! can't opendir $testdir: $!"; my @files = sort grep { /\.sd$/ && -f "$testdir/$_" } readdir(DIR); closedir(DIR); my @profiles; foreach my $profile (@files) { push (@profiles, "$testdir/$profile"); } opendir(DIR, $testdir) or die "Bail out! can't opendir $testdir: $!"; my @dirs = sort grep { /^[^\.]/ && -d "$testdir/$_" } readdir(DIR); closedir(DIR); foreach my $dir (@dirs) { push(@profiles, find_all_tests("$testdir/$dir")); } return @profiles; } my @profiles = find_all_tests($config{'profiledir'}); plan tests => scalar(@profiles); foreach my $profile (@profiles) { test_profile ("$profile"); } apparmor-2.13.3/parser/tst/valgrind_simple.py0000755000175000017500000001064513502024172017055 0ustar jjjj#!/usr/bin/env python3 # ------------------------------------------------------------------ # # Copyright (C) 2013 Canonical Ltd. # Author: Steve Beattie # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ # TODO # - finish adding suppressions for valgrind false positives from argparse import ArgumentParser # requires python 2.7 or newer import os import sys import tempfile import unittest import testlib DEFAULT_TESTDIR = "./simple_tests/vars" VALGRIND_ERROR_CODE = 151 VALGRIND_ARGS = ['--leak-check=full', '--error-exitcode=%d' % (VALGRIND_ERROR_CODE)] VALGRIND_SUPPRESSIONS = ''' { valgrind-serialize_profile-obsessive-overreads Memcheck:Addr4 fun:_Z*sd_serialize_profile* ... fun:_Z*__sd_serialize_profile* fun:_Z*load_profile* fun:_Z*load_policy_list* }''' class AAParserValgrindTests(testlib.AATestTemplate): def setUp(self): # REPORT ALL THE OUTPUT self.maxDiff = None def _runtest(self, testname, config): parser_args = ['-Q', '-I', config.testdir, '-M', './features_files/features.all'] failure_rc = [VALGRIND_ERROR_CODE, testlib.TIMEOUT_ERROR_CODE] command = [config.valgrind] command.extend(VALGRIND_ARGS) command.append(config.parser) command.extend(parser_args) command.append(testname) rc, output = self.run_cmd(command, timeout=120) self.assertNotIn(rc, failure_rc, "valgrind returned error code %d, gave the following output\n%s\ncommand run: %s" % (rc, output, " ".join(command))) def find_testcases(testdir): '''dig testcases out of passed directory''' for (fdir, direntries, files) in os.walk(testdir): for f in files: if f.endswith(".sd"): yield os.path.join(fdir, f) def create_suppressions(): '''generate valgrind suppressions file''' handle, name = tempfile.mkstemp(suffix='.suppressions', prefix='aa-parser-valgrind') os.close(handle) handle = open(name,"w+") handle.write(VALGRIND_SUPPRESSIONS) handle.close() return name def main(): rc = 0 p = ArgumentParser() p.add_argument('-p', '--parser', default=testlib.DEFAULT_PARSER, action="store", dest='parser', help="Specify path of apparmor parser to use [default = %(default)s]") p.add_argument('-v', '--verbose', action="store_true", dest="verbose") p.add_argument('-V', '--valgrind', default='/usr/bin/valgrind', action="store", dest="valgrind", help="Specify path of valgrind to use [default = %(default)s]") p.add_argument('-s', '--skip-suppressions', action="store_true", dest="skip_suppressions", help="Don't use valgrind suppressions to skip false positives") p.add_argument('--dump-suppressions', action="store_true", dest="dump_suppressions", help="Dump valgrind suppressions to stdout") p.add_argument('testdir', action="store", default=DEFAULT_TESTDIR, nargs='?', metavar='dir', help="run tests on alternate directory [default = %(default)s]") config = p.parse_args() if config.dump_suppressions: print(VALGRIND_SUPPRESSIONS) return rc if not os.path.exists(config.valgrind): print("Unable to find valgrind at '%s', ensure that it is installed" % (config.valgrind), file=sys.stderr) exit(1) verbosity = 1 if config.verbose: verbosity = 2 if not config.skip_suppressions: suppression_file = create_suppressions() VALGRIND_ARGS.append('--suppressions=%s' % (suppression_file)) for f in find_testcases(config.testdir): def stub_test(self, testname=f): self._runtest(testname, config) stub_test.__doc__ = "test %s" % (f) setattr(AAParserValgrindTests, 'test_%s' % (f), stub_test) test_suite = unittest.TestSuite() test_suite.addTest(unittest.TestLoader().loadTestsFromTestCase(AAParserValgrindTests)) try: result = unittest.TextTestRunner(verbosity=verbosity).run(test_suite) if not result.wasSuccessful(): rc = 1 except: rc = 1 finally: os.remove(suppression_file) return rc if __name__ == "__main__": rc = main() exit(rc) apparmor-2.13.3/parser/tst/simple_tests/0000755000175000017500000000000013502024172016026 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/readme0000644000175000017500000000006113502024172017203 0ustar jjjjDirectory for auto generated x-transition tests apparmor-2.13.3/parser/tst/simple_tests/profile/0000755000175000017500000000000013502024172017466 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/profile/profile_ns_bad7.sd0000644000175000017500000000035513502024172023056 0ustar jjjj# #=DESCRIPTION collision same profile, same namespace w/ and w/o profile keyword #=EXRESULT FAIL # vim:syntax=apparmor # Last Modified: Thu Feb 11 00:14:20 2016 # :ns:/t { /does/not/exist r, } profile :ns:/t { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/re_ok3.sd0000644000175000017500000000435013502024172021202 0ustar jjjj# #=DESCRIPTION Basic test that re profile names are allowed in quotes #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # "/ **" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } "/ *" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } "/ ?" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } "/ [ab]" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } "/ [^ab]" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile "a **" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile "a *" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile "a ?" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile "a [ab]" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile "a [^ab]" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/simple_named_ok_no_rules.sd0000644000175000017500000000043313502024172025052 0ustar jjjj# #=DESCRIPTION simple syntax test -- no actual rules. #=EXRESULT PASS # profile noexist /does/not/exist { } profile noexist2 /does/not/exist2 { ^hat1 { } ^hat2 { } } profile noexist3 /does/not/exist { } profile noexist4 /does/not/exist2 { ^hat1 { } ^hat2 { } } apparmor-2.13.3/parser/tst/simple_tests/profile/simple_bad_no_close_brace3.sd0000644000175000017500000000027013502024172025214 0ustar jjjj# #=DESCRIPTION A simple syntax error -- no closing brace with hat. #=EXRESULT FAIL # /usr/bin/foo { /usr/bin/foo r, /blah rw, ^hat1 { /foo rw, /var/log/messages w, } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_ns_ok2.sd0000644000175000017500000000123013502024172022725 0ustar jjjj# #=DESCRIPTION same profile different namespaces test, duplicate mode bits #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } :foo:/does/not/exist { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } :bar:/does/not/exist { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } apparmor-2.13.3/parser/tst/simple_tests/profile/profiles_dupe_3.sd0000644000175000017500000000126013502024172023077 0ustar jjjj# #=DESCRIPTION dupe hats in profile #=EXRESULT FAIL # /does/not/exist { ^does/not/exist1 { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } ^does/not/exist2 { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, ^does/not/exist3 { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } ^does/not/exist2 { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } ^does/not/exist4 { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_ns_ok4.sd0000644000175000017500000000125313502024172022734 0ustar jjjj# #=DESCRIPTION same unattached profile different namespaces test, duplicate mode bits #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # profile unattached { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } profile :foo:unattached { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } profile :bar:unattached { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } apparmor-2.13.3/parser/tst/simple_tests/profile/re_named_ok1.sd0000644000175000017500000000235313502024172022345 0ustar jjjj# # $Id$ #=DESCRIPTION Basic test that named profiles with re attachment are allowed #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # profile one /** { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile two /* { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile three /? { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile four /[ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile five /[^ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/re_named_ok4.sd0000644000175000017500000000445313502024172022353 0ustar jjjj# # $Id$ #=DESCRIPTION Basic test that re profile names are allowed after :ns: #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # :ns:one /** { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } :ns:two /* { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } :ns:three /? { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } :ns:four /[ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } :ns:five /[^ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile :ns:six /** { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile :ns:seven /* { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile :ns:eight /? { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile :ns:nine /[ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile :ns:ten /[^ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/re_ok1.sd0000644000175000017500000000427313502024172021204 0ustar jjjj# #=DESCRIPTION Basic test that re profile names are allowed #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /** { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } /* { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } /? { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } /[ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } /[^ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile ** { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile * { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile ? { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile [ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile [^ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/simple_ok_no_rules.sd0000644000175000017500000000022013502024172023700 0ustar jjjj# #=DESCRIPTION simple syntax test -- no actual rules. #=EXRESULT PASS # /does/not/exist { } /does/not/exist2 { ^hat1 { } ^hat2 { } } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_ns_bad5.sd0000644000175000017500000000024613502024172023053 0ustar jjjj# #=DESCRIPTION namespace with no profile name #=EXRESULT FAIL # vim:syntax=apparmor # Last Modified: Thu Feb 11 00:14:20 2016 # :namespace: { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_ns_named_ok3.sd0000644000175000017500000000233313502024172024077 0ustar jjjj# # $Id$ #=DESCRIPTION same named profile mixed with unnamed same attach different namespaces test, #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # profile /does/not/exist { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } :foo:/does/not/exist { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } profile :bar:/does/not/exist { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } profile exist /does/not/exist { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } :foo:exist /does/not/exist { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } profile :bar:exist /does/not/exist { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_basic_ok1.sd0000644000175000017500000000054413502024172023374 0ustar jjjj# #=DESCRIPTION Basic parsing test, duplicate mode bits #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/profiles_dupe_1.sd0000644000175000017500000000052513502024172023100 0ustar jjjj# #=DESCRIPTION dupe profiles #=EXRESULT FAIL # /does/not/exist { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } /does/not/exist2 { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } /does/not/exist2 { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_basic_named_ok1.sd0000644000175000017500000000060613502024172024537 0ustar jjjj# # $Id$ #=DESCRIPTION Basic parsing test, name profile duplicate mode bits #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # profile exist /does/not/exist { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/entry_mods_audit_ok1.sd0000644000175000017500000000045613502024172024146 0ustar jjjj# #=DESCRIPTION test audit flag for file rules #=EXRESULT PASS # /usr/bin/foo { audit /foo rw, audit /foo/** rw, /tmp/** rw, audit rw /bar, audit rw /bar/**, rw /var/tmp/**, audit { /one rw, /one/** rw, rw /two, rw /two/**, } audit /audit r, audit { } } apparmor-2.13.3/parser/tst/simple_tests/profile/simple_bad_no_program_name.sd0000644000175000017500000000015113502024172025335 0ustar jjjj# #=DESCRIPTION A simple syntax error -- no program #=EXRESULT FAIL # { /usr/bin/foo r, /blah rw, } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_basic_ok2.sd0000644000175000017500000000054613502024172023377 0ustar jjjj# #=DESCRIPTION Basic parsing test, unattached profile #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # profile notattached { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/re_ok2.sd0000644000175000017500000000436313502024172021205 0ustar jjjj# #=DESCRIPTION Basic test that re local profile names are allowed #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /foo//** { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } /foo//* { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } /foo//? { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } /foo//[ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } /foo//[^ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile foo//** { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile foo//* { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile foo//? { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile foo//[ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile foo//[^ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/simple_bad_no_close_brace1.sd0000644000175000017500000000017213502024172025213 0ustar jjjj# #=DESCRIPTION A simple syntax error -- no closing brace #=EXRESULT FAIL # /usr/bin/foo { /usr/bin/foo r, /blah rw, apparmor-2.13.3/parser/tst/simple_tests/profile/re_ok4.sd0000644000175000017500000000435613502024172021211 0ustar jjjj# #=DESCRIPTION Basic test that re profile names are allowed after :ns: #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # :ns:/** { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } :ns:/* { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } :ns:/? { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } :ns:/[ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } :ns:/[^ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile :ns:** { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile :ns:* { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile :ns:? { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile :ns:[ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile :ns:[^ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/re_named_ok3.sd0000644000175000017500000000451613502024172022352 0ustar jjjj# # $Id$ #=DESCRIPTION Basic test that named re profile names are allowed in quotes #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # profile one "/ **" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile two "/ *" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile three "/ ?" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile four "/ [ab]" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile five "/ [^ab]" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile six "/ **" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile seven "/ *" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile eight "/ ?" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile nine "/ [ab]" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile ten "/ [^ab]" { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/profiles_dupe_2.sd0000644000175000017500000000103213502024172023073 0ustar jjjj# #=DESCRIPTION dupe profiles #=EXRESULT FAIL # /does/not/exist1 { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } /does/not/exist2 { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } /does/not/exist { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } /does/not/exist2 { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist3 { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } apparmor-2.13.3/parser/tst/simple_tests/profile/simple_bad_no_opening_brace1.sd0000644000175000017500000000017213502024172025545 0ustar jjjj# #=DESCRIPTION A simple syntax error -- no opening brace #=EXRESULT FAIL # /usr/bin/foo /usr/bin/foo r, /blah rw, } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_ns_bad3.sd0000644000175000017500000000054313502024172023051 0ustar jjjj# #=DESCRIPTION collision same profile, same namespace #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # :/does/not/exist { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_ns_named_ok2.sd0000644000175000017500000000130713502024172024076 0ustar jjjj# # $Id$ #=DESCRIPTION same named profile different namespaces test, duplicate mode bits #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # profile exist /does/not/exist { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } :foo:exist /does/not/exist { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } profile :bar:exist /does/not/exist { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_ns_bad6.sd0000644000175000017500000000035713502024172023057 0ustar jjjj# #=DESCRIPTION collision same profile, same namespace with profile keyword #=EXRESULT FAIL # vim:syntax=apparmor # Last Modified: Thu Feb 11 00:14:20 2016 # profile :ns:/t { /does/not/exist r, } profile :ns:/t { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_ns_bad8.sd0000644000175000017500000000030213502024172023047 0ustar jjjj# #=DESCRIPTION no terminating ':' for ns namespace (w/ profile keyword) #=EXRESULT FAIL # vim:syntax=apparmor # Last Modified: Thu Feb 11 00:14:20 2016 # profile :ns/t { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/re_named_ok2.sd0000644000175000017500000000452113502024172022345 0ustar jjjj# # $Id$ #=DESCRIPTION Basic test that named re local profile names are allowed #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /foo//local1 /** { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } /foo//local2 /* { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } /foo//local3 /? { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } /foo//local4 /[ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } /foo//local5 /[^ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile foo//local6 /** { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile foo//local7 /* { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile foo//local8 /? { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile foo//local9 /[ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile foo//local10 /[^ab] { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/simple_bad_nomode.sd0000644000175000017500000000014413502024172023455 0ustar jjjj# #=DESCRIPTION A simple syntax error #=EXRESULT FAIL # /usr/bin/foo { /usr/bin/foo r, blah, } apparmor-2.13.3/parser/tst/simple_tests/profile/simple_bad_no_close_brace2.sd0000644000175000017500000000027013502024172025213 0ustar jjjj# #=DESCRIPTION A simple syntax error -- no closing brace with hat. #=EXRESULT FAIL # /usr/bin/foo { /usr/bin/foo r, /blah rw, ^hat1 { /foo rw, } /var/log/messages w, apparmor-2.13.3/parser/tst/simple_tests/profile/profile_ns_ok3.sd0000644000175000017500000000123313502024172022731 0ustar jjjj# #=DESCRIPTION same unattached profile different namespaces test, duplicate mode bits #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # profile unattached { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } :foo:unattached { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } :bar:unattached { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } apparmor-2.13.3/parser/tst/simple_tests/profile/re_ok5.sd0000644000175000017500000000433213502024172021204 0ustar jjjj# #=DESCRIPTION Basic test that re profile names are allowed that aren't trailing #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /**a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } /*a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } /?a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } /[ab]a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } /[^ab]a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile **a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile *a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile ?a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile [ab]a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile [^ab]a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/exploding_profile.sd0000644000175000017500000000316113502024172023530 0ustar jjjj#=DESCRIPTION Test of dfa tree optimization #=EXRESULT PASS #This profile exercises the dfa tree optimization #Without working tree optimization this profile generates a dfa with 100,000s #of states and that requires several gigs, and takes hours to compute #With working tree optimization this profile generates a dfa with about 3,000 #states and takes a second or two to compute. /foo { /a/b/c/webdir/config.inc.php rw, /a/b/c/** r, /a/b/c/upload/** rw, /a/b/c/webdir/cms/files/** rw, /a/b/c/webdir/content/** rw, /a/b/c/webdir/mitarbeiter/** rw, /a/b/c/webdir/newsletter/** wr, /a/b/c/webdir/pnTemp/** rw, /a/b/c/webdir/redaxo/include/generated/articles/** rw, /a/b/c/webdir/typo3/ext/** rw, /a/b/c/webdir/wiki/images/** rw, /a/b/c/**.txt rw, /a/b/c/**.log rw, /a/b/c/webdir/**/com_docman/docman.config.php wr, /a/b/c/webdir/**/settings.php wr, /a/b/c/webdir/**.txt rw, /a/b/c/webdir/upload/**{.jpg,.pdf,.ps,.gif,.png,.ppt,.doc,.txt,.rtf} rw, /a/b/c/webdir/courses/uploaded_file*/** rw, /a/b/c/webdir/**/conf*.php rw, /a/b/c/**{cache,data,download,/ext,fileadmin,files,images,joomla,moodledata/sessions}/** rw, /a/b/c/**log{,s}/** rw, /a/b/c/**typo3{conf,temp}/** rw, /a/b/c/webdir/**/components/** rw, /a/b/c/webdir/content/**/conf/** rw, /a/b/c/webdir/**/content/** rw, /a/b/c/webdir/**/{pages,pictures,data,doc,files,languages,media}/** rw, /a/b/c/webdir/**/{pages,pictures}/** rw, /a/b/c/webdir/**/module{s,}/** rw, /a/b/c/webdir/**/{templates_c,templates,temp,tmp}/** rw, /a/b/c/webdir/**/upload/** rw, /a/b/c/webdir/**count*/** rw, /a/b/c/webdir/**/**uploads/** rw, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/0000755000175000017500000000000013502024172020562 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad3.sd0000644000175000017500000000042513502024172023100 0ustar jjjj# #=DESCRIPTION Ensure really bad parsing fails #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(blahblab { /usr/X11R6/lib/lib*so* r /does/not/exist r } audit) { /usr/X11R6/lib/lib*so* r, /does/not/exist2 r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_ok1.sd0000644000175000017500000000142313502024172022760 0ustar jjjj# #=DESCRIPTION validate some uses of the profile flags. #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(chroot_relative) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist1 flags=(audit, chroot_relative) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist2 flags=(chroot_relative, audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist3 flags=(complain, chroot_relative) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist4 flags=(chroot_relative, complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_ok6.sd0000644000175000017500000000146613502024172022774 0ustar jjjj# #=DESCRIPTION validate some uses of the profile flags. #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(no_attach_disconnected) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist1 flags=(audit, no_attach_disconnected) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist2 flags=(no_attach_disconnected, audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist3 flags=(complain, no_attach_disconnected) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist4 flags=(no_attach_disconnected, complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad4.sd0000644000175000017500000000037113502024172023101 0ustar jjjj# #=DESCRIPTION Bad flags parsing should fail #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=({{{ }} { } { } audit {{}}}{{{} {}{}{} / ^ ) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad6.sd0000644000175000017500000000033213502024172023100 0ustar jjjj# #=DESCRIPTION Don't accept other keyword as a flag #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist (capability) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_ok.sd0000644000175000017500000000244713502024172022706 0ustar jjjj# #=DESCRIPTION validate some uses of the profile flags. #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist2 flags=(audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist2 r, } /does/not/exist3 flags=(complain,audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist5 r, } /does/not/exist4 flags=(audit,complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist7 r, } /does/not/exist5 flags=(audit,complain,audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist8 r, } /does/not/exist6 (complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist7 (audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist2 r, } /does/not/exist8 (complain,audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist5 r, } /does/not/exist9 (audit,complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist7 r, } /does/not/exist10 (audit,complain,audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist8 r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad13.sd0000644000175000017500000000037013502024172023160 0ustar jjjj# #=DESCRIPTION Ensure debug flag is no longer accepted #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(chroot_attach, chroot_no_attach) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad14.sd0000644000175000017500000000026313502024172023162 0ustar jjjj# #=DESCRIPTION fail if flags is not speeled correctly #=EXRESULT FAIL # vim:syntax=apparmor # /does/not/exist flogs=(audit) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad15.sd0000644000175000017500000000034113502024172023160 0ustar jjjj# #=DESCRIPTION Ensure namespace_relative and chroot_relative conflict #=EXRESULT FAIL # vim:syntax=apparmor # /does/not/exist flags=(namespace_relative, chroot_relative) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_ok_whitespace.sd0000644000175000017500000000102713502024172025113 0ustar jjjj# #=DESCRIPTION verify whitespace is allowed in profile flags. #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist3 flags=(complain, audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist5 r, } /does/not/exist4 flags = (audit , complain){ #include /usr/X11R6/lib/lib*so* r, /does/not/exist7 r, } /does/not/exist5 flags = ( audit , complain , audit ) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist8 r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_ok2.sd0000644000175000017500000000144213502024172022762 0ustar jjjj# #=DESCRIPTION validate some uses of the profile flags. #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(namespace_relative) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist1 flags=(audit, namespace_relative) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist2 flags=(namespace_relative, audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist3 flags=(complain, namespace_relative) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist4 flags=(namespace_relative, complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad10.sd0000644000175000017500000000037413502024172023161 0ustar jjjj# #=DESCRIPTION Ensure conflicting namespace flags fail #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(chroot_relative, namepace_relative) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad17.sd0000644000175000017500000000022513502024172023163 0ustar jjjj# #=DESCRIPTION Ensure empty (whitespace-only) flags fail #=EXRESULT FAIL # vim:syntax=apparmor # /does/not/exist ( ) { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad_debug_3.sd0000644000175000017500000000035313502024172024405 0ustar jjjj# #=DESCRIPTION Ensure debug flag is no longer accepted #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist3 flags=(debug,complain) { /usr/X11R6/lib/lib*so* r, /does/not/exist5 r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad18.sd0000644000175000017500000000034113502024172023163 0ustar jjjj# #=DESCRIPTION Ensure debug flag is no longer accepted #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist2 (audit,debug) { /usr/X11R6/lib/lib*so* r, /does/not/exist2 r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad16.sd0000644000175000017500000000020313502024172023156 0ustar jjjj# #=DESCRIPTION Ensure empty flags fail #=EXRESULT FAIL # vim:syntax=apparmor # /does/not/exist flags=() { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_ok5.sd0000644000175000017500000000144713502024172022772 0ustar jjjj# #=DESCRIPTION validate some uses of the profile flags. #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(attach_disconnected) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist1 flags=(audit, attach_disconnected) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist2 flags=(attach_disconnected, audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist3 flags=(complain, attach_disconnected) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist4 flags=(attach_disconnected, complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_ok3.sd0000644000175000017500000000142313502024172022762 0ustar jjjj# #=DESCRIPTION validate some uses of the profile flags. #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(mediate_deleted) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist1 flags=(audit, mediate_deleted) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist2 flags=(mediate_deleted, audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist3 flags=(complain, mediate_deleted) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist4 flags=(mediate_deleted, complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad12.sd0000644000175000017500000000042413502024172023157 0ustar jjjj# #=DESCRIPTION Ensure conflicting disconnested flags generate an error #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(attach_disconnected, no_attach_disconnected) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_ok9.sd0000644000175000017500000000761613502024172023002 0ustar jjjj# #=DESCRIPTION validate some uses of the profile flags. #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # #============================== /does/not/exist flags=(chroot_relative, mediate_deleted) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist1 flags=(audit, chroot_relative, mediate_deleted) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist2 flags=(chroot_relative, mediate_deleted, audit) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist3 flags=(complain, chroot_relative, mediate_deleted) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist4 flags=(chroot_relative, mediate_deleted, complain) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } #------- /does/not/exist11 flags=(chroot_relative, delegate_deleted) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist12 flags=(audit, chroot_relative, delegate_deleted) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist13 flags=(chroot_relative, delegate_deleted, audit) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist14 flags=(complain, chroot_relative, delegate_deleted) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist15 flags=(chroot_relative, delegate_deleted, complain) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } #------- /does/not/exist21 flags=(chroot_relative, attach_disconnected) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist22 flags=(audit, chroot_relative, attach_disconnected) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist23 flags=(chroot_relative, attach_disconnected, audit) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist24 flags=(complain, chroot_relative, attach_disconnected) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist25 flags=(chroot_relative, attach_disconnected, complain) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } #------- /does/not/exist31 flags=(chroot_relative, no_attach_disconnected) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist32 flags=(audit, chroot_relative, no_attach_disconnected) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist33 flags=(chroot_relative, no_attach_disconnected, audit) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist34 flags=(complain, chroot_relative, no_attach_disconnected) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist35 flags=(chroot_relative, no_attach_disconnected, complain) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } #------- /does/not/exist41 flags=(chroot_relative, chroot_attach) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist42 flags=(audit, chroot_relative, chroot_attach) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist43 flags=(chroot_relative, chroot_attach, audit) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist44 flags=(complain, chroot_relative, chroot_attach) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist45 flags=(chroot_relative, chroot_attach, complain) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } #------- /does/not/exist51 flags=(chroot_relative, chroot_no_attach) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist52 flags=(audit, chroot_relative, chroot_no_attach) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist53 flags=(chroot_relative, chroot_no_attach, audit) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist54 flags=(complain, chroot_relative, chroot_no_attach) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist55 flags=(chroot_relative, chroot_no_attach, complain) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_hats_ok.sd0000644000175000017500000001104313502024172023715 0ustar jjjj# #=DESCRIPTION validate some uses of the profile flags with hats. #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, ^FOO { #include } } /does/not/exist2 flags=(complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist2 r, ^FOO flags=(complain) { #include } ^FOO2 (complain) { #include } } /does/not/exist3 flags=(complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist3 r, ^FOO flags=(audit) { #include } ^FOO2 (audit) { #include } } /does/not/exist4 { #include /usr/X11R6/lib/lib*so* r, /does/not/exist4 r, ^FOO flags=(complain) { #include } ^FOO2 (complain) { #include } } /does/not/exist5 flags=(audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist5 r, ^FOO { #include } } /does/not/exist6 flags=(audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist6 r, ^FOO flags=(audit) { #include } ^FOO2 (audit) { #include } } /does/not/exist7 flags=(audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist7 r, ^FOO flags=(complain) { #include } ^FOO2 (complain) { #include } } /does/not/exist8 { #include /usr/X11R6/lib/lib*so* r, /does/not/exist8 r, ^FOO flags=(audit) { #include } ^FOO2 (audit) { #include } } /does/not/exist9 { #include /usr/X11R6/lib/lib*so* r, /does/not/exist9 r, ^FOO flags=(audit) { #include } ^FOO2 (audit) { #include } ^BAR { #include } ^BAZ flags=(audit) { #include } ^BAZ2 (audit) { #include } ^BIF flags=(complain) { #include } ^BIF2 (complain) { #include } ^BUZ flags=(complain,audit) { /var/log/messages r, } ^BUZ2 (complain,audit) { /var/log/messages r, } } /does/not/exist11 flags=(complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, ^FOO { #include } } /does/not/exist12 flags=(complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist2 r, ^FOO flags=(complain) { #include } ^FOO2 (complain) { #include } } /does/not/exist13 flags=(complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist3 r, ^FOO flags=(audit) { #include } ^FOO2 (audit) { #include } } /does/not/exist14 { #include /usr/X11R6/lib/lib*so* r, /does/not/exist4 r, ^FOO flags=(complain) { #include } ^FOO2 (complain) { #include } } /does/not/exist15 flags=(audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist5 r, ^FOO { #include } } /does/not/exist16 flags=(audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist6 r, ^FOO flags=(audit) { #include } ^FOO2 (audit) { #include } } /does/not/exist17 flags=(audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist7 r, ^FOO flags=(complain) { #include } ^FOO2 (complain) { #include } } /does/not/exist18 { #include /usr/X11R6/lib/lib*so* r, /does/not/exist8 r, ^FOO flags=(audit) { #include } ^FOO2 (audit) { #include } } /does/not/exist19 { #include /usr/X11R6/lib/lib*so* r, /does/not/exist9 r, ^FOO flags=(audit) { #include } ^FOO2 (audit) { #include } ^BAR { #include } ^BAZ flags=(audit) { #include } ^BAZ2 (audit) { #include } ^BIF flags=(complain) { #include } ^BIF2 (complain) { #include } ^BUZ flags=(complain,audit) { /var/log/messages r, } ^BUZ2 (complain,audit) { /var/log/messages r, } } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_ok10.sd0000644000175000017500000000047213502024172023043 0ustar jjjj# #=DESCRIPTION validate some uses of the profile flags. #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(chroot_relative, mediate_deleted, attach_disconnected, chroot_attach) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad_debug_4.sd0000644000175000017500000000044113502024172024404 0ustar jjjj# #=DESCRIPTION Ensure debug flag is no longer accepted #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist4 flags=(audit,complain) { /usr/X11R6/lib/lib*so* r, /does/not/exist7 r, ^debug flags=(debug) { /var/log/debug rwl, } } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad_debug_1.sd0000644000175000017500000000033713502024172024405 0ustar jjjj# #=DESCRIPTION Ensure debug flag is no longer accepted #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(debug) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad8.sd0000644000175000017500000000036313502024172023106 0ustar jjjj# #=DESCRIPTION Bad flags parsing should fail #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist ({{{ }} { } { } audit {{}}}{{{} {}{}{} / ^ ) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad20.sd0000644000175000017500000000045713502024172023164 0ustar jjjj# #=DESCRIPTION Ensure debug flag is no longer accepted (even if it's inside a hat) #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist4 (audit,complain) { /usr/X11R6/lib/lib*so* r, /does/not/exist7 r, ^debug (debug) { /var/log/debug rwl, } } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad11.sd0000644000175000017500000000040313502024172023153 0ustar jjjj# #=DESCRIPTION Ensure conflicting deletion flags cause an error #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(mediate_deleted, delegate_deleted) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad5.sd0000644000175000017500000000033113502024172023076 0ustar jjjj# #=DESCRIPTION Ensure debug flag is no longer accepted #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist (debug) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad7.sd0000644000175000017500000000041713502024172023105 0ustar jjjj# #=DESCRIPTION Ensure really bad parsing fails #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist (blahblab { /usr/X11R6/lib/lib*so* r /does/not/exist r } audit) { /usr/X11R6/lib/lib*so* r, /does/not/exist2 r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad2.sd0000644000175000017500000000034013502024172023073 0ustar jjjj# #=DESCRIPTION Don't accept other keyword as a flag #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(capability) { /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_ok7.sd0000644000175000017500000000141113502024172022763 0ustar jjjj# #=DESCRIPTION validate some uses of the profile flags. #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(chroot_attach) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist1 flags=(audit, chroot_attach) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist2 flags=(chroot_attach, audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist3 flags=(complain, chroot_attach) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist4 flags=(chroot_attach, complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_ok4.sd0000644000175000017500000000143013502024172022761 0ustar jjjj# #=DESCRIPTION validate some uses of the profile flags. #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(delegate_deleted) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist1 flags=(audit, delegate_deleted) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist2 flags=(delegate_deleted, audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist3 flags=(complain, delegate_deleted) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist4 flags=(delegate_deleted, complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad_debug_2.sd0000644000175000017500000000034713502024172024407 0ustar jjjj# #=DESCRIPTION Ensure debug flag is no longer accepted #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist2 flags=(audit,debug) { /usr/X11R6/lib/lib*so* r, /does/not/exist2 r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_bad19.sd0000644000175000017500000000034313502024172023166 0ustar jjjj# #=DESCRIPTION Ensure debug flag is no longer accepted #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist3 (debug,complain) { /usr/X11R6/lib/lib*so* r, /does/not/exist5 r, } apparmor-2.13.3/parser/tst/simple_tests/profile/flags/flags_ok8.sd0000644000175000017500000000143013502024172022765 0ustar jjjj# #=DESCRIPTION validate some uses of the profile flags. #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist flags=(chroot_no_attach) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist1 flags=(audit, chroot_no_attach) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist2 flags=(chroot_no_attach, audit) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist3 flags=(complain, chroot_no_attach) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } /does/not/exist4 flags=(chroot_no_attach, complain) { #include /usr/X11R6/lib/lib*so* r, /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_bad1.sd0000644000175000017500000000045513502024172022351 0ustar jjjj# #=DESCRIPTION unattached profile without profile keyword #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # unattached { /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_ns_bad4.sd0000644000175000017500000000054413502024172023053 0ustar jjjj# #=DESCRIPTION collision same profile, same namespace #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # ::/does/not/exist { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_ns_bad1.sd0000644000175000017500000000106613502024172023050 0ustar jjjj# #=DESCRIPTION collision same profile, same namespace #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # :foo:/exists { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } :foo:/exists { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/simple_bad_no_close_brace4.sd0000644000175000017500000000032313502024172025214 0ustar jjjj# #=DESCRIPTION A simple syntax error -- no closing brace with hat. #=EXRESULT FAIL # /usr/bin/foo { /usr/bin/foo r, /blah rw, ^hat1 { /foo rw, ^hat2 { /bar rw, } /var/log/messages w, } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_ns_named_ok1.sd0000644000175000017500000000116713502024172024101 0ustar jjjj# # $Id$ #=DESCRIPTION Basic namespace test wit named profile, duplicate mode bits #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # :foo:exist /does/not/exist { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile :foo:exist2 /does/not/exist2 { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/local/0000755000175000017500000000000013502024172020560 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/profile/local/local_named_profiles_ok2.sd0000644000175000017500000000112613502024172026024 0ustar jjjj# # $Id$ #=DESCRIPTION More basic parsing test of local (internal) profiles #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /bin/ls ixixixix, /bin/echo uxuxuxuxux, profile grep /bin/grep { #include /bin/grep r, /tmp/shmeegol rwm, } capability setuid, profile cat /bin/cat { #include /bin/cat r, /tmp/shmeegol w, } /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, } apparmor-2.13.3/parser/tst/simple_tests/profile/local/local_named_profiles_ok1.sd0000644000175000017500000000073113502024172026024 0ustar jjjj# # $Id$ #=DESCRIPTION Basic parsing test of local (internal) profiles #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, profile grep /bin/grep { #include /bin/grep r, /tmp/shmeegol rwm, } } apparmor-2.13.3/parser/tst/simple_tests/profile/local/local_named_profile_ok1.sd0000644000175000017500000000067113502024172025644 0ustar jjjj# #=DESCRIPTION simple local (interior) named profile cases #=EXRESULT PASS # /does/not/exist { /foo rw, /foo/** rw, rw /bar, rw /bar/**, profile /bin/grep { /one rw, /one/** rw, rw /two, rw /two/**, } hat GREP { /one r, /one/** r, r /two, r /two/**, } profile true /bin/true { /three rw, /three/** rw, rw /four, rw /four/**, } profile false /bin/false { } } apparmor-2.13.3/parser/tst/simple_tests/profile/local/local_profiles_ok1.sd0000644000175000017500000000071513502024172024662 0ustar jjjj# #=DESCRIPTION Basic parsing test of local (internal) profiles #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, profile /bin/grep { #include /bin/grep r, /tmp/shmeegol rwm, } } apparmor-2.13.3/parser/tst/simple_tests/profile/local/local_profile_ok1.sd0000644000175000017500000000065013502024172024475 0ustar jjjj# #=DESCRIPTION simple local (interior) profile cases #=EXRESULT PASS # /does/not/exist { /foo rw, /foo/** rw, rw /bar, rw /bar/**, profile /bin/grep { /one rw, /one/** rw, rw /two, rw /two/**, } hat GREP { /one r, /one/** r, r /two, r /two/**, } profile /bin/true { /three rw, /three/** rw, rw /four, rw /four/**, } profile /bin/false { } } apparmor-2.13.3/parser/tst/simple_tests/profile/local/local_profiles_ok2.sd0000644000175000017500000000110613502024172024656 0ustar jjjj# #=DESCRIPTION More basic parsing test of local (internal) profiles #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /bin/ls ixixixix, /bin/echo uxuxuxuxux, profile /bin/grep { #include /bin/grep r, /tmp/shmeegol rwm, } capability setuid, profile /bin/cat { #include /bin/cat r, /tmp/shmeegol w, } /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_ns_ok1.sd0000644000175000017500000000201413502024172022725 0ustar jjjj# #=DESCRIPTION Basic namespace test, duplicate mode bits #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # :foo:/does/not/exist { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile :foo:/does/not/exist2 { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } :foo:unattached { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile :foo:unattached2 { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/profile_ns_bad2.sd0000644000175000017500000000054613502024172023053 0ustar jjjj# #=DESCRIPTION collision same profile, same namespace #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # foo:/does/not/exist { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/profile/re_named_ok5.sd0000644000175000017500000000450013502024172022345 0ustar jjjj# # $Id$ #=DESCRIPTION Basic test that re profile names are allowed that aren't trailing #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # profile one /**a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile two /*a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile three /?a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile four /[ab]a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile five /[^ab]a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile size /**a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile seven /*a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile eight /?a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile nine /[ab]a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } profile ten /[^ab]a { #include /usr/X11R6/lib/lib*so* rrr, /does/not/exist r, /var/log/messages www, /tmp/sd*.foo rwrwwrll, /bin/cat pxpxpxpxpx, /bin/ls ixixixix, /bin/echo uxuxuxuxux, } apparmor-2.13.3/parser/tst/simple_tests/rewrite/0000755000175000017500000000000013502024172017507 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/rewrite/alias_good_5.sd0000644000175000017500000000043613502024172022367 0ustar jjjj#=DESCRIPTION Test of aliases within includes #=EXRESULT PASS alias /tmp -> /var/tmp, #include #include @{FOO} += /etc/ alias /etc/ -> /Config/, /bin/foo { #include /tmp/meep rw, @{FOO}/some/other/thing r, } apparmor-2.13.3/parser/tst/simple_tests/rewrite/alias_good_1.sd0000644000175000017500000000022413502024172022356 0ustar jjjj#=DESCRIPTION Simple test of alias functionality #=EXRESULT PASS alias /tmp -> /var/tmp, /bin/foo { #include /tmp/meep rw, } apparmor-2.13.3/parser/tst/simple_tests/rewrite/alias_good_2.sd0000644000175000017500000000040213502024172022355 0ustar jjjj#=DESCRIPTION Simple test of alias functionality after var defn #=EXRESULT PASS alias /etc -> /Etcetera, @{FOO}= foo bar alias /tmp -> /var/tmp, @{MEEP} = meep moop alias /usr -> /User, /bin/foo { #include /tmp/@{FOO}/@{MEEP} rw, } apparmor-2.13.3/parser/tst/simple_tests/rewrite/alias_dupe_1.sd0000644000175000017500000000041513502024172022365 0ustar jjjj#=DESCRIPTION Test of duplicate alias detection #=EXRESULT PASS @{MEEP} = meep moop alias /etc -> /Etcetera, alias /usr/ -> /Libraries/, alias /tmp -> /var/tmp, alias /usr/ -> /User/, @{FOO} = foo bar /bin/foo { #include /tmp/@{FOO}/@{MEEP} rw, } apparmor-2.13.3/parser/tst/simple_tests/rewrite/alias_good_4.sd0000644000175000017500000000036413502024172022366 0ustar jjjj#=DESCRIPTION Test of aliases within includes #=EXRESULT PASS alias /tmp -> /var/tmp, #include #include /bin/foo { #include /tmp/meep rw, @{FOO}/some/other/thing r, } apparmor-2.13.3/parser/tst/simple_tests/rewrite/alias_good_3.sd0000644000175000017500000000042113502024172022357 0ustar jjjj#=DESCRIPTION Simple test of alias functionality #=EXRESULT PASS @{MEEP} = meep moop alias /etc -> /Etcetera, alias /tmp -> /var/tmp, alias /usr/lib/ -> /Libraries/, alias /usr -> /User, @{FOO} = foo bar /bin/foo { #include /tmp/@{FOO}/@{MEEP} rw, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/0000755000175000017500000000000013502024172017304 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_03.sd0000644000175000017500000000014213502024172020544 0ustar jjjj# #=Description basic allow ptrace all rule #=EXRESULT PASS # /usr/bin/foo { allow ptrace, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_06.sd0000644000175000017500000000013613502024172020552 0ustar jjjj# #=Description basic ptrace trace rule #=EXRESULT PASS # /usr/bin/foo { ptrace trace, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_01.sd0000644000175000017500000000012613502024172020544 0ustar jjjj# #=Description basic ptrace all rule #=EXRESULT PASS # /usr/bin/foo { ptrace, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_21.sd0000644000175000017500000000017413502024172020551 0ustar jjjj# #=Description ptrace regex peer rule #=EXRESULT PASS # /usr/bin/foo { deny ptrace read peer=/{**/,}bin/{sh,true}, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_11.sd0000644000175000017500000000030013502024172020537 0ustar jjjj# #=Description basic ptrace all perms rule #=EXRESULT PASS # /usr/bin/foo { ptrace (read, readby, trace, tracedby) , ptrace read, ptrace readby, ptrace trace, ptrace tracedby, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/bad_01.sd0000644000175000017500000000017013502024172020660 0ustar jjjj# #=Description basic ptrace all perms rule #=EXRESULT FAIL # /usr/bin/foo { ptrace read readby trace tracedby , } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_04.sd0000644000175000017500000000014213502024172020545 0ustar jjjj# #=Description basic audit ptrace all rule #=EXRESULT PASS # /usr/bin/foo { audit ptrace, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/bad_05.sd0000644000175000017500000000015713502024172020671 0ustar jjjj# #=Description capability + ptrace merged rule #=EXRESULT FAIL # /usr/bin/foo { capability ptrace trace, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_02.sd0000644000175000017500000000014013502024172020541 0ustar jjjj# #=Description basic deny ptrace all rule #=EXRESULT PASS # /usr/bin/foo { deny ptrace, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_16.sd0000644000175000017500000000032513502024172020553 0ustar jjjj# #=Description basic ptrace peer perms rule #=EXRESULT PASS # @{SHELL}=/bin/bash /usr/bin/foo { ptrace peer=/bin/true, ptrace peer=/sbin/init, ptrace peer=@{SHELL}, ptrace peer=SOME_OTHER_PROFILE, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_10.sd0000644000175000017500000000017613502024172020551 0ustar jjjj# #=Description basic ptrace readby and tracedby all rule #=EXRESULT PASS # /usr/bin/foo { ptrace (readby, tracedby) , } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_07.sd0000644000175000017500000000014013502024172020546 0ustar jjjj# #=Description basic ptrace readby rule #=EXRESULT PASS # /usr/bin/foo { ptrace readby, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_12.sd0000644000175000017500000000026713502024172020554 0ustar jjjj# #=Description basic ptrace all perms rule #=EXRESULT PASS # /usr/bin/foo { ptrace (read readby trace tracedby) , ptrace (read, readby) , ptrace trace, ptrace tracedby, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_09.sd0000644000175000017500000000016413502024172020556 0ustar jjjj# #=Description basic ptrace read and trace all rule #=EXRESULT PASS # /usr/bin/foo { ptrace (read, trace) , } apparmor-2.13.3/parser/tst/simple_tests/ptrace/bad_09.sd0000644000175000017500000000012513502024172020670 0ustar jjjj# #=Description ptrace w/owner #=EXRESULT FAIL # /usr/bin/foo { owner ptrace r, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/bad_07.sd0000644000175000017500000000016713502024172020674 0ustar jjjj# #=Description peer not allowed perms list #=EXRESULT FAIL # /usr/bin/foo { ptrace (read readby peer=/dev/null), } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_08.sd0000644000175000017500000000015013502024172020550 0ustar jjjj# #=Description basic ptrace tracedby all rule #=EXRESULT PASS # /usr/bin/foo { ptrace tracedby, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_15.sd0000644000175000017500000000015413502024172020552 0ustar jjjj# #=Description basic ptrace peer perms rule #=EXRESULT PASS # /usr/bin/foo { ptrace peer=/bin/true, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/bad_outside_01.sd0000644000175000017500000000012313502024172022412 0ustar jjjj# #=Description ptrace all rule outside of a profile #=EXRESULT FAIL # ptrace, apparmor-2.13.3/parser/tst/simple_tests/ptrace/bad_04.sd0000644000175000017500000000022613502024172020665 0ustar jjjj# #=Description basic ptrace bad multi-peer perms rule #=EXRESULT FAIL # /usr/bin/foo { ptrace peer=/bin/true peer=/sbin/init peer=MY_PROFILE, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_19.sd0000644000175000017500000000050413502024172020555 0ustar jjjj# #=Description ptrace peer w/perms rule #=EXRESULT PASS # /usr/bin/foo { ptrace read peer=/bin/sh, ptrace write peer=/bin/true, ptrace trace peer=/bin/false, ptrace readby peer=/sbin/init, ptrace tracedby peer=/usr/bin/gdb, ptrace rw peer=/usr/bin/top, ptrace (readby, tracedby) peer=/usr/bin/valgrind, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_14.sd0000644000175000017500000000017313502024172020552 0ustar jjjj# #=Description basic ptrace list perms rule #=EXRESULT PASS # /usr/bin/foo { ptrace (w read, r rw,,,, tracedby ) , } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_20.sd0000644000175000017500000000016713502024172020552 0ustar jjjj# #=Description ptrace regex peer rule #=EXRESULT PASS # /usr/bin/foo { ptrace read peer=/{**/,}bin/{sh,true}, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_18.sd0000644000175000017500000000023713502024172020557 0ustar jjjj# #=Description ptrace peer w/multiple var names rule #=EXRESULT PASS # @{SHELLS}=/bin/bash /bin/dash /bin/tcsh /usr/bin/foo { ptrace peer=@{SHELLS}, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/bad_06.sd0000644000175000017500000000017413502024172020671 0ustar jjjj# #=Description capability + ptrace merged rule #=EXRESULT FAIL # /usr/bin/foo { capability sys_ptrace peer=/dev/null, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_05.sd0000644000175000017500000000013413502024172020547 0ustar jjjj# #=Description basic ptrace read rule #=EXRESULT PASS # /usr/bin/foo { ptrace read, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/bad_02.sd0000644000175000017500000000014613502024172020664 0ustar jjjj# #=Description basic ptrace bad peer rule #=EXRESULT FAIL # /usr/bin/foo { ptrace /bin/true , } apparmor-2.13.3/parser/tst/simple_tests/ptrace/bad_03.sd0000644000175000017500000000017213502024172020664 0ustar jjjj# #=Description basic ptrace bad peer rule #=EXRESULT FAIL # /usr/bin/foo { ptrace read peer=/sbin/init /bin/bash, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_22.sd0000644000175000017500000000060413502024172020550 0ustar jjjj# #=Description ptrace peer w/perms and misc modifiers rule #=EXRESULT PASS # /usr/bin/foo { deny ptrace read peer=/bin/sh, allow ptrace write peer=/bin/true, audit ptrace trace peer=/bin/false, audit deny ptrace readby peer=/sbin/init, audit allow ptrace tracedby peer=/usr/bin/gdb, ptrace rw peer=/usr/bin/top, deny ptrace (readby, tracedby) peer=/usr/bin/valgrind, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_13.sd0000644000175000017500000000033513502024172020551 0ustar jjjj# #=Description basic ptrace all perms rule #=EXRESULT PASS # /usr/bin/foo { ptrace (read readby trace write tracedby r w rw) , ptrace (w read, r rw, write) , ptrace r, ptrace rw, ptrace w, ptrace write, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/bad_10.sd0000644000175000017500000000015313502024172020661 0ustar jjjj# #=Description ptrace w/bad regex expansion #=EXRESULT FAIL # /usr/bin/foo { ptrace peer={/bin/true, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/ok_17.sd0000644000175000017500000000020013502024172020544 0ustar jjjj# #=Description ptrace peer w/implicit profile name rule #=EXRESULT PASS # /usr/bin/foo { ptrace peer=@{profile_name}, } apparmor-2.13.3/parser/tst/simple_tests/ptrace/bad_08.sd0000644000175000017500000000014713502024172020673 0ustar jjjj# #=Description ptrace w/non ptrace modifier #=EXRESULT FAIL # /usr/bin/foo { ptrace bus=session, } apparmor-2.13.3/parser/tst/simple_tests/file/0000755000175000017500000000000013502024172016745 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/file/ok_deny_2.sd0000644000175000017500000000016413502024172021147 0ustar jjjj# #=DESCRIPTION A simple deny rule #=EXRESULT PASS # vim:syntax=apparmor # /usr/bin/foo { deny /usr/bin/foo r, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_quoted_2.sd0000644000175000017500000000015713502024172021513 0ustar jjjj# #=DESCRIPTION simple quoted newline expansion #=EXRESULT PASS # profile test { "/bin/alpha\nbeta" rix, } apparmor-2.13.3/parser/tst/simple_tests/file/var1_src_ok_audit_deny_link.sd0000644000175000017500000000017713502024172024735 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { audit deny link @{var} -> /tmp/**, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_comma_2.sd0000644000175000017500000000013513502024172021302 0ustar jjjj# #=DESCRIPTION comma at end of pathname #=EXRESULT PASS # /usr/bin/foo { "/foobar," r, } apparmor-2.13.3/parser/tst/simple_tests/file/bad_embedded_0_1.sd0000644000175000017500000000023613502024172022274 0ustar jjjj# #=DESCRIPTION embedded \000 in file path #=EXRESULT PASS # currently do NOT have semantic checks for \000 in file path # /usr/bin/foo { /foo\000bar w, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_4.sd0000644000175000017500000000020413502024172020125 0ustar jjjj# #=Description basic inherit uppercase exec permission (should emit warning) #=EXRESULT PASS # /usr/bin/foo { /usr/bin/foo iX, } apparmor-2.13.3/parser/tst/simple_tests/file/var1_target_ok_link_2.sd0000644000175000017500000000020413502024172023437 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { link /alpha/beta -> @{var}, @{var} r, } apparmor-2.13.3/parser/tst/simple_tests/file/bad_embedded_spaces_1.sd0000644000175000017500000000013713502024172023413 0ustar jjjj#=DESCRIPTION Simple test case for embedded spaces #=EXRESULT FAIL /bin/foo { /abc def r, } apparmor-2.13.3/parser/tst/simple_tests/file/var1_src_ok_link_3.sd0000644000175000017500000000021013502024172022736 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { link subset @{var} -> /tmp/**, /tmp/** r, } apparmor-2.13.3/parser/tst/simple_tests/file/var2_src_ok_link_3.sd0000644000175000017500000000021413502024172022743 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { link subset /foo@{var} -> /tmp/**, /tmp/** r, } apparmor-2.13.3/parser/tst/simple_tests/file/var1_target_ok_deny_link.sd0000644000175000017500000000017513502024172024244 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { deny link /alpha/beta -> @{var}, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_bare_1.sd0000644000175000017500000000017113502024172021116 0ustar jjjj# #=Description bare file rule #=EXRESULT PASS #=TODO https://launchpad.net/bugs/1215637 # /usr/bin/foo { deny file, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_link_2.sd0000644000175000017500000000017113502024172021143 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # profile test { link /alpha/beta -> /tmp/**, /tmp/** r, } apparmor-2.13.3/parser/tst/simple_tests/file/var2_ok_link_3.sd0000644000175000017500000000022213502024172022073 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { link subset /foo@{var} -> /foo@{var}, /foo@{var} r, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_mmap_1.sd0000644000175000017500000000027413502024172021143 0ustar jjjj# #=DESCRIPTION m and [uUpPi]x do not conflict #=EXRESULT PASS # /usr/bin/foo { /bin/cat mix, /bin/true mpx, /bin/false mux, /lib/libc.so rwlm, /bin/less mUx, /bin/more mPx, } apparmor-2.13.3/parser/tst/simple_tests/file/var1_src_ok_link_1.sd0000644000175000017500000000016713502024172022747 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { @{var} rl, /gamma/* rwl, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_quoted_4.sd0000644000175000017500000000015513502024172021513 0ustar jjjj# #=DESCRIPTION simple quoted quote expansion #=EXRESULT PASS # profile test { "/bin/alpha\"beta" rix, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_append_1.sd0000644000175000017500000000025513502024172021457 0ustar jjjj# #=DESCRIPTION test append #=EXRESULT PASS # /usr/bin/foo { /bin/cat a, /bin/true ra, /bin/false ma, /lib/libc.so la, /bin/less ixa, /bin/more pxa, /a uxa, } apparmor-2.13.3/parser/tst/simple_tests/file/var2_ok_deny_link.sd0000644000175000017500000000020013502024172022664 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { deny link /foo@{var} -> /foo@{var}, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_5.sd0000644000175000017500000000020713502024172020131 0ustar jjjj# #=Description basic unconfined uppercase exec permission (should emit warning) #=EXRESULT PASS # /usr/bin/foo { /usr/bin/foo UX, } apparmor-2.13.3/parser/tst/simple_tests/file/bad_append_2.sd0000644000175000017500000000016313502024172021573 0ustar jjjj# #=DESCRIPTION a and w conflict (reverse order from bad_append_1.sd) #=EXRESULT FAIL # /usr/bin/foo { /a aw, } apparmor-2.13.3/parser/tst/simple_tests/file/var2_target_ok_deny_link.sd0000644000175000017500000000020113502024172024233 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { deny link /alpha/beta -> /foo@{var}, } apparmor-2.13.3/parser/tst/simple_tests/file/var1_ok_link_2.sd0000644000175000017500000000017713502024172022102 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { link @{var} -> @{var}, @{var} r, } apparmor-2.13.3/parser/tst/simple_tests/file/bad_re_brace_3.sd0000644000175000017500000000022013502024172022061 0ustar jjjj# #=DESCRIPTION alternation braces '{}' with only one entry should be an error #=EXRESULT FAIL # profile failure { /usr/bin/one{en}try rw, } apparmor-2.13.3/parser/tst/simple_tests/file/bad_re_brace_1.sd0000644000175000017500000000016113502024172022063 0ustar jjjj# #=DESCRIPTION regex with empty character class (brace) #=EXRESULT FAIL # /usr/bin/foo { /alpha/[]beta rw, } apparmor-2.13.3/parser/tst/simple_tests/file/var2_src_ok_link_2.sd0000644000175000017500000000020513502024172022742 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { link /foo@{var} -> /tmp/**, /tmp/** r, } apparmor-2.13.3/parser/tst/simple_tests/file/front_perms_ok_1.sd0000644000175000017500000000047013502024172022545 0ustar jjjj# #=DESCRIPTION perms before pathname #=EXRESULT PASS # /usr/bin/foo { r /foo1, w /foo1, a /foo1, k /foo1, m /foo1, l /foo1, px /foo1, Px /foo2, ux /foo3, Ux /foo4, ix /foo5, unsafe px /foo6, unsafe Px /foo7, unsafe ux /foo8, unsafe Ux /foo9, unsafe ix /foo10, } apparmor-2.13.3/parser/tst/simple_tests/file/var2_ok_audit_deny_link.sd0000644000175000017500000000020613502024172024060 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { audit deny link /foo@{var} -> /foo@{var}, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_carat_1.sd0000644000175000017500000000012413502024172021275 0ustar jjjj# #=DESCRIPTION carat in pathname #=EXRESULT PASS # /usr/bin/foo { /foo^bar r, } apparmor-2.13.3/parser/tst/simple_tests/file/var1_src_ok_link_2.sd0000644000175000017500000000020113502024172022735 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { link @{var} -> /tmp/**, /tmp/** r, } apparmor-2.13.3/parser/tst/simple_tests/file/var1_target_ok_audit_deny_link.sd0000644000175000017500000000020313502024172025422 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { audit deny link /alpha/beta -> @{var}, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_slashquote_1.sd0000644000175000017500000000020713502024172022375 0ustar jjjj# #=DESCRIPTION unnecessary slash quotes are okay (should emit warning) #=EXRESULT PASS # profile blart { /bingo/bang\o/bongo rw, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_deny_link.sd0000644000175000017500000000016113502024172021740 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # profile test { deny link /alpha/beta -> /tmp/**, } apparmor-2.13.3/parser/tst/simple_tests/file/var1_ok_link_3.sd0000644000175000017500000000020613502024172022074 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { link subset @{var} -> @{var}, @{var} r, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_alternations_3.sd0000644000175000017500000001244413502024172022720 0ustar jjjj# #=Description basic file rule w/large number of alternations #=EXRESULT PASS # /usr/bin/foo { /{a/a,a/b,a/c,a/d,a/e,a/f,a/g,a/h,a/i,a/j,a/k,a/l,a/m,a/n,a/o,a/p,a/q,a/r,a/s,a/t,a/u,a/v,a/w,a/x,a/y,a/z,a/A,a/B,a/C,a/D,a/E,a/F,a/G,a/H,a/I,a/J,a/K,a/L,a/M,a/N,a/O,a/P,a/Q,a/R,a/S,a/T,a/U,a/V,a/W,a/X,a/Y,a/Z,b/a,b/b,b/c,b/d,b/e,b/f,b/g,b/h,b/i,b/j,b/k,b/l,b/m,b/n,b/o,b/p,b/q,b/r,b/s,b/t,b/u,b/v,b/w,b/x,b/y,b/z,b/A,b/B,b/C,b/D,b/E,b/F,b/G,b/H,b/I,b/J,b/K,b/L,b/M,b/N,b/O,b/P,b/Q,b/R,b/S,b/T,b/U,b/V,b/W,b/X,b/Y,b/Z,c/a,c/b,c/c,c/d,c/e,c/f,c/g,c/h,c/i,c/j,c/k,c/l,c/m,c/n,c/o,c/p,c/q,c/r,c/s,c/t,c/u,c/v,c/w,c/x,c/y,c/z,c/A,c/B,c/C,c/D,c/E,c/F,c/G,c/H,c/I,c/J,c/K,c/L,c/M,c/N,c/O,c/P,c/Q,c/R,c/S,c/T,c/U,c/V,c/W,c/X,c/Y,c/Z,d/a,d/b,d/c,d/d,d/e,d/f,d/g,d/h,d/i,d/j,d/k,d/l,d/m,d/n,d/o,d/p,d/q,d/r,d/s,d/t,d/u,d/v,d/w,d/x,d/y,d/z,d/A,d/B,d/C,d/D,d/E,d/F,d/G,d/H,d/I,d/J,d/K,d/L,d/M,d/N,d/O,d/P,d/Q,d/R,d/S,d/T,d/U,d/V,d/W,d/X,d/Y,d/Z,e/a,e/b,e/c,e/d,e/e,e/f,e/g,e/h,e/i,e/j,e/k,e/l,e/m,e/n,e/o,e/p,e/q,e/r,e/s,e/t,e/u,e/v,e/w,e/x,e/y,e/z,e/A,e/B,e/C,e/D,e/E,e/F,e/G,e/H,e/I,e/J,e/K,e/L,e/M,e/N,e/O,e/P,e/Q,e/R,e/S,e/T,e/U,e/V,e/W,e/X,e/Y,e/Z,f/a,f/b,f/c,f/d,f/e,f/f,f/g,f/h,f/i,f/j,f/k,f/l,f/m,f/n,f/o,f/p,f/q,f/r,f/s,f/t,f/u,f/v,f/w,f/x,f/y,f/z,f/A,f/B,f/C,f/D,f/E,f/F,f/G,f/H,f/I,f/J,f/K,f/L,f/M,f/N,f/O,f/P,f/Q,f/R,f/S,f/T,f/U,f/V,f/W,f/X,f/Y,f/Z,g/a,g/b,g/c,g/d,g/e,g/f,g/g,g/h,g/i,g/j,g/k,g/l,g/m,g/n,g/o,g/p,g/q,g/r,g/s,g/t,g/u,g/v,g/w,g/x,g/y,g/z,g/A,g/B,g/C,g/D,g/E,g/F,g/G,g/H,g/I,g/J,g/K,g/L,g/M,g/N,g/O,g/P,g/Q,g/R,g/S,g/T,g/U,g/V,g/W,g/X,g/Y,g/Z,h/a,h/b,h/c,h/d,h/e,h/f,h/g,h/h,h/i,h/j,h/k,h/l,h/m,h/n,h/o,h/p,h/q,h/r,h/s,h/t,h/u,h/v,h/w,h/x,h/y,h/z,h/A,h/B,h/C,h/D,h/E,h/F,h/G,h/H,h/I,h/J,h/K,h/L,h/M,h/N,h/O,h/P,h/Q,h/R,h/S,h/T,h/U,h/V,h/W,h/X,h/Y,h/Z,i/a,i/b,i/c,i/d,i/e,i/f,i/g,i/h,i/i,i/j,i/k,i/l,i/m,i/n,i/o,i/p,i/q,i/r,i/s,i/t,i/u,i/v,i/w,i/x,i/y,i/z,i/A,i/B,i/C,i/D,i/E,i/F,i/G,i/H,i/I,i/J,i/K,i/L,i/M,i/N,i/O,i/P,i/Q,i/R,i/S,i/T,i/U,i/V,i/W,i/X,i/Y,i/Z,j/a,j/b,j/c,j/d,j/e,j/f,j/g,j/h,j/i,j/j,j/k,j/l,j/m,j/n,j/o,j/p,j/q,j/r,j/s,j/t,j/u,j/v,j/w,j/x,j/y,j/z,j/A,j/B,j/C,j/D,j/E,j/F,j/G,j/H,j/I,j/J,j/K,j/L,j/M,j/N,j/O,j/P,j/Q,j/R,j/S,j/T,j/U,j/V,j/W,j/X,j/Y,j/Z,k/a,k/b,k/c,k/d,k/e,k/f,k/g,k/h,k/i,k/j,k/k,k/l,k/m,k/n,k/o,k/p,k/q,k/r,k/s,k/t,k/u,k/v,k/w,k/x,k/y,k/z,k/A,k/B,k/C,k/D,k/E,k/F,k/G,k/H,k/I,k/J,k/K,k/L,k/M,k/N,k/O,k/P,k/Q,k/R,k/S,k/T,k/U,k/V,k/W,k/X,k/Y,k/Z,l/a,l/b,l/c,l/d,l/e,l/f,l/g,l/h,l/i,l/j,l/k,l/l,l/m,l/n,l/o,l/p,l/q,l/r,l/s,l/t,l/u,l/v,l/w,l/x,l/y,l/z,l/A,l/B,l/C,l/D,l/E,l/F,l/G,l/H,l/I,l/J,l/K,l/L,l/M,l/N,l/O,l/P,l/Q,l/R,l/S,l/T,l/U,l/V,l/W,l/X,l/Y,l/Z,m/a,m/b,m/c,m/d,m/e,m/f,m/g,m/h,m/i,m/j,m/k,m/l,m/m,m/n,m/o,m/p,m/q,m/r,m/s,m/t,m/u,m/v,m/w,m/x,m/y,m/z,m/A,m/B,m/C,m/D,m/E,m/F,m/G,m/H,m/I,m/J,m/K,m/L,m/M,m/N,m/O,m/P,m/Q,m/R,m/S,m/T,m/U,m/V,m/W,m/X,m/Y,m/Z,n/a,n/b,n/c,n/d,n/e,n/f,n/g,n/h,n/i,n/j,n/k,n/l,n/m,n/n,n/o,n/p,n/q,n/r,n/s,n/t,n/u,n/v,n/w,n/x,n/y,n/z,n/A,n/B,n/C,n/D,n/E,n/F,n/G,n/H,n/I,n/J,n/K,n/L,n/M,n/N,n/O,n/P,n/Q,n/R,n/S,n/T,n/U,n/V,n/W,n/X,n/Y,n/Z,o/a,o/b,o/c,o/d,o/e,o/f,o/g,o/h,o/i,o/j,o/k,o/l,o/m,o/n,o/o,o/p,o/q,o/r,o/s,o/t,o/u,o/v,o/w,o/x,o/y,o/z,o/A,o/B,o/C,o/D,o/E,o/F,o/G,o/H,o/I,o/J,o/K,o/L,o/M,o/N,o/O,o/P,o/Q,o/R,o/S,o/T,o/U,o/V,o/W,o/X,o/Y,o/Z,p/a,p/b,p/c,p/d,p/e,p/f,p/g,p/h,p/i,p/j,p/k,p/l,p/m,p/n,p/o,p/p,p/q,p/r,p/s,p/t,p/u,p/v,p/w,p/x,p/y,p/z,p/A,p/B,p/C,p/D,p/E,p/F,p/G,p/H,p/I,p/J,p/K,p/L,p/M,p/N,p/O,p/P,p/Q,p/R,p/S,p/T,p/U,p/V,p/W,p/X,p/Y,p/Z,q/a,q/b,q/c,q/d,q/e,q/f,q/g,q/h,q/i,q/j,q/k,q/l,q/m,q/n,q/o,q/p,q/q,q/r,q/s,q/t,q/u,q/v,q/w,q/x,q/y,q/z,q/A,q/B,q/C,q/D,q/E,q/F,q/G,q/H,q/I,q/J,q/K,q/L,q/M,q/N,q/O,q/P,q/Q,q/R,q/S,q/T,q/U,q/V,q/W,q/X,q/Y,q/Z,r/a,r/b,r/c,r/d,r/e,r/f,r/g,r/h,r/i,r/j,r/k,r/l,r/m,r/n,r/o,r/p,r/q,r/r,r/s,r/t,r/u,r/v,r/w,r/x,r/y,r/z,r/A,r/B,r/C,r/D,r/E,r/F,r/G,r/H,r/I,r/J,r/K,r/L,r/M,r/N,r/O,r/P,r/Q,r/R,r/S,r/T,r/U,r/V,r/W,r/X,r/Y,r/Z,s/a,s/b,s/c,s/d,s/e,s/f,s/g,s/h,s/i,s/j,s/k,s/l,s/m,s/n,s/o,s/p,s/q,s/r,s/s,s/t,s/u,s/v,s/w,s/x,s/y,s/z,s/A,s/B,s/C,s/D,s/E,s/F,s/G,s/H,s/I,s/J,s/K,s/L,s/M,s/N,s/O,s/P,s/Q,s/R,s/S,s/T,s/U,s/V,s/W,s/X,s/Y,s/Z,t/a,t/b,t/c,t/d,t/e,t/f,t/g,t/h,t/i,t/j,t/k,t/l,t/m,t/n,t/o,t/p,t/q,t/r,t/s,t/t,t/u,t/v,t/w,t/x,t/y,t/z,t/A,t/B,t/C,t/D,t/E,t/F,t/G,t/H,t/I,t/J,t/K,t/L,t/M,t/N,t/O,t/P,t/Q,t/R,t/S,t/T,t/U,t/V,t/W,t/X,t/Y,t/Z,u/a,u/b,u/c,u/d,u/e,u/f,u/g,u/h,u/i,u/j,u/k,u/l,u/m,u/n,u/o,u/p,u/q,u/r,u/s,u/t,u/u,u/v,u/w,u/x,u/y,u/z,u/A,u/B,u/C,u/D,u/E,u/F,u/G,u/H,u/I,u/J,u/K,u/L,u/M,u/N,u/O,u/P,u/Q,u/R,u/S,u/T,u/U,u/V,u/W,u/X,u/Y,u/Z,v/a,v/b,v/c,v/d,v/e,v/f,v/g,v/h,v/i,v/j,v/k,v/l,v/m,v/n,v/o,v/p,v/q,v/r,v/s,v/t,v/u,v/v,v/w,v/x,v/y,v/z,v/A,v/B,v/C,v/D,v/E,v/F,v/G,v/H,v/I,v/J,v/K,v/L,v/M,v/N,v/O,v/P,v/Q,v/R,v/S,v/T,v/U,v/V,v/W,v/X,v/Y,v/Z,w/a,w/b,w/c,w/d,w/e,w/f,w/g,w/h,w/i,w/j,w/k,w/l,w/m,w/n,w/o,w/p,w/q,w/r,w/s,w/t,w/u,w/v,w/w,w/x,w/y,w/z,w/A,w/B,w/C,w/D,w/E,w/F,w/G,w/H,w/I,w/J,w/K,w/L,w/M,w/N,w/O,w/P,w/Q,w/R,w/S,w/T,w/U,w/V,w/W,w/X,w/Y,w/Z,x/a,x/b,x/c,x/d,x/e,x/f,x/g,x/h,x/i,x/j,x/k,x/l,x/m,x/n,x/o,x/p,x/q,x/r,x/s,x/t,x/u,x/v,x/w,x/x,x/y,x/z,x/A,x/B,x/C,x/D,x/E,x/F,x/G,x/H,x/I,x/J,x/K,x/L,x/M,x/N,x/O,x/P,x/Q,x/R,x/S,x/T,x/U,x/V,x/W,x/X,x/Y,x/Z,y/a,y/b,y/c,y/d,y/e,y/f,y/g,y/h,y/i,y/j,y/k,y/l,y/m,y/n,y/o,y/p,y/q,y/r,y/s,y/t,y/u,y/v,y/w,y/x,y/y,y/z,y/A,y/B,y/C,y/D,y/E,y/F,y/G,y/H,y/I,y/J,y/K,y/L,y/M,y/N,y/O,y/P,y/Q,y/R,y/S,y/T,y/U,y/V,y/W,y/X,y/Y,y/Z,z/a,z/b,z/c,z/d,z/e,z/f,z/g,z/h,z/i,z/j,z/k,z/l,z/m,z/n,z/o,z/p,z/q,z/r,z/s,z/t,z/u,z/v,z/w,z/x,z/y,z/z} rw, } apparmor-2.13.3/parser/tst/simple_tests/file/file/0000755000175000017500000000000013502024172017664 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/file/file/ok_comma_2.sd0000644000175000017500000000014213502024172022217 0ustar jjjj# #=DESCRIPTION comma at end of pathname #=EXRESULT PASS # /usr/bin/foo { file "/foobar," r, } apparmor-2.13.3/parser/tst/simple_tests/file/file/bad_embedded_spaces_1.sd0000644000175000017500000000014413502024172024330 0ustar jjjj#=DESCRIPTION Simple test case for embedded spaces #=EXRESULT FAIL /bin/foo { file /abc def r, } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_mmap_1.sd0000644000175000017500000000033213502024172022055 0ustar jjjj# #=DESCRIPTION m and [uUpPi]x do not conflict #=EXRESULT PASS # /usr/bin/foo { file /bin/cat mix, file /bin/true mpx, file /bin/false mux, file /lib/libc.so rwlm, file /bin/less mUx, file /bin/more mPx, } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_append_1.sd0000644000175000017500000000032013502024172022367 0ustar jjjj# #=DESCRIPTION test append #=EXRESULT PASS # /usr/bin/foo { file /bin/cat a, file /bin/true ra, file /bin/false ma, file /lib/libc.so la, file /bin/less ixa, file /bin/more pxa, file /a uxa, } apparmor-2.13.3/parser/tst/simple_tests/file/file/bad_1.sd0000644000175000017500000000011613502024172021160 0ustar jjjj# #=Description basic file rule #=EXRESULT FAIL # /usr/bin/foo { file rw, } apparmor-2.13.3/parser/tst/simple_tests/file/file/front_perms_ok_1.sd0000644000175000017500000000061113502024172023461 0ustar jjjj# #=DESCRIPTION perms before pathname #=EXRESULT PASS # /usr/bin/foo { file r /foo1, file w /foo1, file a /foo1, file k /foo1, file m /foo1, file l /foo1, file px /foo1, file Px /foo2, file ux /foo3, file Ux /foo4, file ix /foo5, file unsafe px /foo6, file unsafe Px /foo7, file unsafe ux /foo8, file unsafe Ux /foo9, file unsafe ix /foo10, } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_carat_1.sd0000644000175000017500000000013113502024172022212 0ustar jjjj# #=DESCRIPTION carat in pathname #=EXRESULT PASS # /usr/bin/foo { file /foo^bar r, } apparmor-2.13.3/parser/tst/simple_tests/file/file/bad_lock_1.sd0000644000175000017500000000013113502024172022165 0ustar jjjj# #=DESCRIPTION k to be lower case #=EXRESULT FAIL # /usr/bin/foo { file /bin/ls K, } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_alternations_1.sd0000644000175000017500000000026613502024172023634 0ustar jjjj# #=Description basic file rule w/alternations #=EXRESULT PASS # /usr/bin/foo { file /a/b/c/**{cache,data,download,/ext,fileadmin,files,images,joomla,moodledata/sessions}/** rw, } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_3.sd0000644000175000017500000000020113502024172021040 0ustar jjjj# #=DESCRIPTION A simple successful profile #=EXRESULT PASS # /usr/bin/foo { file /usr/bin/foo r, file /usr/bin/blah rix, } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_embedded_spaces_1.sd0000644000175000017500000000014713502024172024216 0ustar jjjj#=DESCRIPTION Simple test case for embedded spaces #=EXRESULT PASS /bin/foo { file "/abc\ def" r, } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_mmap_2.sd0000644000175000017500000000041413502024172022057 0ustar jjjj# #=DESCRIPTION m and [upi]x do not conflict, seperate rules #=EXRESULT PASS # /usr/bin/foo { file /bin/cat rm, file /bin/cat ix, file /bin/true px, file /bin/true m, file /bin/false m, file /bin/false ux, file /lib/libc.so rwl, file /lib/libc.so m, } apparmor-2.13.3/parser/tst/simple_tests/file/file/bad_comma_1.sd0000644000175000017500000000013213502024172022332 0ustar jjjjk# #=DESCRIPTION comma in pathname #=EXRESULT FAIL # /usr/bin/foo { file /foobar, r, } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_embedded_spaces_2.sd0000644000175000017500000000014613502024172024216 0ustar jjjj#=DESCRIPTION Simple test case for embedded spaces #=EXRESULT PASS /bin/foo { file "/abc def" r, } apparmor-2.13.3/parser/tst/simple_tests/file/file/dos_line_endings.sd0000644000175000017500000000256113502024172023523 0ustar jjjj# vim:syntax=subdomain # Last Modified: Wed Aug 31 11:14:09 2005 #=DESCRIPTION dos line endings #=EXRESULT PASS /usr/lib/RealPlayer10/realplay { #include #include file /bin/bash ix, file /bin/sed ixr, file /bin/true ixr, file /etc/opt/gnome/pango/pango.modules r, file /opt/gnome/lib/gtk-2.0/2.4.0/loaders/* r, file /opt/gnome/lib/lib*so* r, file /opt/gnome/lib/pango/1.4.0/modules/* r, file /opt/gnome/share/icons r, file /opt/gnome/share/icons/** r, file /opt/gnome/bin/nautilus rux, file /root r, file /root/.Xauthority r, file /root/.fonts.cache-1 r, file /root/.realplayerrc rw, file /home/*/ r, file /home/*/.Xauthority r, file /home/*/.fonts.cache-1 r, file /home/*/.realplayerrc rw, file /usr/X11R6/lib/Acrobat7/Resource/Font/* r, file /usr/X11R6/lib/Acrobat7/Resource/Font/PFM/* r, file /usr/lib/RealPlayer10/** r, file /usr/lib/RealPlayer10/realplay.bin ixr, file /usr/lib/jvm/java-1.4.2-sun-1.4.2.06/jre/lib/fonts/** r, file /usr/lib/ooo-2.0/share/fonts/** r, file /opt/MozillaFirefox/bin/firefox.sh pxr, file /opt/MozillaFirefox/lib/firefox-bin pxr, file /opt/MozillaFirefox/lib/init.d r, file /usr/bin/opera pxr, file /usr/share/icons r, file /usr/share/icons/** r, file /opt/gnome/share/pixmaps r, file /opt/gnome/share/pixmaps/** r, } apparmor-2.13.3/parser/tst/simple_tests/file/file/bad_append_1.sd0000644000175000017500000000012313502024172022505 0ustar jjjj# #=DESCRIPTION w and a conflict #=EXRESULT FAIL # /usr/bin/foo { file /a wa, } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_embedded_spaces_4.sd0000644000175000017500000000014513502024172024217 0ustar jjjj#=DESCRIPTION Simple test case for embedded spaces #=EXRESULT PASS /bin/foo { file /abc\ def r, } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_inv_char_class.sd0000644000175000017500000000013513502024172023662 0ustar jjjj# #=DESCRIPTION carat in pathname #=EXRESULT PASS # /usr/bin/foo { file /foo[^me]bar r, } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_comma_1.sd0000644000175000017500000000013113502024172022214 0ustar jjjj# #=DESCRIPTION comma in pathname #=EXRESULT PASS # /usr/bin/foo { file /foo,bar r, } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_carat_2.sd0000644000175000017500000000014313502024172022216 0ustar jjjj# #=DESCRIPTION trailing carat in pathname #=EXRESULT PASS # /usr/bin/foo { file /foo/bar^ r, } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_embedded_spaces_3.sd0000644000175000017500000000015113502024172024213 0ustar jjjj#=DESCRIPTION Simple test case for embedded spaces #=EXRESULT PASS "/bin/fo o" { file "/abc def" r, } apparmor-2.13.3/parser/tst/simple_tests/file/file/owner/0000755000175000017500000000000013502024172021016 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/file/file/owner/bad_5.sd0000644000175000017500000000020013502024172022310 0ustar jjjj# #=DESCRIPTION owner rules must have comma termination #=EXRESULT FAIL # /usr/bin/foo { owner file /foo rw file /bar rw, } apparmor-2.13.3/parser/tst/simple_tests/file/file/owner/bad_6.sd0000644000175000017500000000015713502024172022324 0ustar jjjj# #=DESCRIPTION owner not allowed after forward perm #=EXRESULT FAIL # /usr/bin/foo { file rw owner /foo, } apparmor-2.13.3/parser/tst/simple_tests/file/file/owner/bad_4.sd0000644000175000017500000000015113502024172022314 0ustar jjjj# #=DESCRIPTION owner cannot follow permission #=EXRESULT FAIL # /usr/bin/foo { file /foo rw owner, } apparmor-2.13.3/parser/tst/simple_tests/file/file/owner/bad_8.sd0000644000175000017500000000015713502024172022326 0ustar jjjj# #=DESCRIPTION owner block needs } termination #=EXRESULT FAIL # /usr/bin/foo { owner { file rw foo, } apparmor-2.13.3/parser/tst/simple_tests/file/file/owner/bad_7.sd0000644000175000017500000000017313502024172022323 0ustar jjjj# #=DESCRIPTION owner not allowed after pathname in forward rule #=EXRESULT FAIL # /usr/bin/foo { file rw /foo owner, } apparmor-2.13.3/parser/tst/simple_tests/file/file/owner/bad_3.sd0000644000175000017500000000015113502024172022313 0ustar jjjj# #=DESCRIPTION owner can not follow path name #=EXRESULT FAIL # /usr/bin/foo { file /foo owner rw, } apparmor-2.13.3/parser/tst/simple_tests/file/file/owner/ok_1.sd0000644000175000017500000000044113502024172022176 0ustar jjjj# #=DESCRIPTION test owner flag for file rules #=EXRESULT PASS # /usr/bin/foo { owner file /foo rw, owner file /foo/** rw, owner file rw /bar, owner file rw /bar/**, owner { file /one rw, file /one/** rw, file rw /two, file rw /two/**, } owner { } } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_alternations_2.sd0000644000175000017500000000027313502024172023633 0ustar jjjj# #=Description basic file rule w/nested alternations #=EXRESULT PASS # /usr/bin/foo { file /a/b/c/**{cache,data,download,/ext,file{admin,s},images,joomla,moodledata/sessions}/** rw, } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_lock_1.sd0000644000175000017500000000043713502024172022061 0ustar jjjj# #=DESCRIPTION k and other perms do not conflict #=EXRESULT PASS # /usr/bin/foo { file /bin/a k, file /bin/b rk, file /bin/c wk, file /bin/d ak, file /bin/e lk, file /bin/e mk, file /bin/f pxk, file /bin/g Pxk, file /bin/h ixk, file /bin/i uxk, file /bin/j Uxk, } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_2.sd0000644000175000017500000000011313502024172021041 0ustar jjjj# #=Description basic file rule #=EXRESULT PASS # /usr/bin/foo { file, } apparmor-2.13.3/parser/tst/simple_tests/file/file/ok_1.sd0000644000175000017500000000013213502024172021041 0ustar jjjj# #=Description basic file rule #=EXRESULT PASS # /usr/bin/foo { file /usr/bin/foo r, } apparmor-2.13.3/parser/tst/simple_tests/file/bad_re_brace_2.sd0000644000175000017500000000017713502024172022073 0ustar jjjj# #=DESCRIPTION empty alternation braces '{}' should be an error #=EXRESULT FAIL # profile failure { /usr/bin/{}snort rw, } apparmor-2.13.3/parser/tst/simple_tests/file/bad_link_outside.sd0000644000175000017500000000014513502024172022574 0ustar jjjj# #=DESCRIPTION link rule outside of a profile #=EXRESULT FAIL # deny link /alpha/beta -> /tmp/**, apparmor-2.13.3/parser/tst/simple_tests/file/ok_quoted_3.sd0000644000175000017500000000016713502024172021515 0ustar jjjj# #=DESCRIPTION simple quoted carriage return expansion #=EXRESULT PASS # profile test { "/bin/alpha\rbeta" rix, } apparmor-2.13.3/parser/tst/simple_tests/file/var1_ok_link_1.sd0000644000175000017500000000016713502024172022100 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { @{var} rl, /gamma/* rwl, } apparmor-2.13.3/parser/tst/simple_tests/file/bad_lock_1.sd0000644000175000017500000000012413502024172021250 0ustar jjjj# #=DESCRIPTION k to be lower case #=EXRESULT FAIL # /usr/bin/foo { /bin/ls K, } apparmor-2.13.3/parser/tst/simple_tests/file/var2_src_ok_deny_link.sd0000644000175000017500000000017513502024172023546 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { deny link /foo@{var} -> /tmp/**, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_alternations_1.sd0000644000175000017500000000026113502024172022710 0ustar jjjj# #=Description basic file rule w/alternations #=EXRESULT PASS # /usr/bin/foo { /a/b/c/**{cache,data,download,/ext,fileadmin,files,images,joomla,moodledata/sessions}/** rw, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_3.sd0000644000175000017500000000016713502024172020134 0ustar jjjj# #=DESCRIPTION A simple successful profile #=EXRESULT PASS # /usr/bin/foo { /usr/bin/foo r, /usr/bin/blah rix, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_deny_4.sd0000644000175000017500000000022213502024172021144 0ustar jjjj# #=DESCRIPTION an exact overlapping deny rule #=EXRESULT PASS # vim:syntax=apparmor # /usr/bin/foo { /usr/bin/foo r, deny /usr/bin/foo r, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_deny_3.sd0000644000175000017500000000021313502024172021143 0ustar jjjj# #=DESCRIPTION an overlapping deny rule #=EXRESULT PASS # vim:syntax=apparmor # /usr/bin/foo { /usr/bin/** r, deny /usr/bin/foo r, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_embedded_spaces_1.sd0000644000175000017500000000014213502024172023272 0ustar jjjj#=DESCRIPTION Simple test case for embedded spaces #=EXRESULT PASS /bin/foo { "/abc\ def" r, } apparmor-2.13.3/parser/tst/simple_tests/file/var2_src_ok_link_1.sd0000644000175000017500000000017313502024172022745 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { /foo@{var} rl, /gamma/* rwl, } apparmor-2.13.3/parser/tst/simple_tests/file/var2_target_ok_link_1.sd0000644000175000017500000000017413502024172023445 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { /alpha/beta rl, /gamma/* rwl, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_mmap_2.sd0000644000175000017500000000034413502024172021142 0ustar jjjj# #=DESCRIPTION m and [upi]x do not conflict, seperate rules #=EXRESULT PASS # /usr/bin/foo { /bin/cat rm, /bin/cat ix, /bin/true px, /bin/true m, /bin/false m, /bin/false ux, /lib/libc.so rwl, /lib/libc.so m, } apparmor-2.13.3/parser/tst/simple_tests/file/bad_comma_1.sd0000644000175000017500000000012513502024172021415 0ustar jjjjk# #=DESCRIPTION comma in pathname #=EXRESULT FAIL # /usr/bin/foo { /foobar, r, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_link_3.sd0000644000175000017500000000020013502024172021135 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # profile test { link subset /alpha/beta -> /tmp/**, /tmp/** r, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_embedded_spaces_2.sd0000644000175000017500000000014113502024172023272 0ustar jjjj#=DESCRIPTION Simple test case for embedded spaces #=EXRESULT PASS /bin/foo { "/abc def" r, } apparmor-2.13.3/parser/tst/simple_tests/file/dos_line_endings.sd0000644000175000017500000000232113502024172022576 0ustar jjjj# vim:syntax=subdomain # Last Modified: Wed Aug 31 11:14:09 2005 #=DESCRIPTION dos line endings #=EXRESULT PASS /usr/lib/RealPlayer10/realplay { #include #include /bin/bash ix, /bin/sed ixr, /bin/true ixr, /etc/opt/gnome/pango/pango.modules r, /opt/gnome/lib/gtk-2.0/2.4.0/loaders/* r, /opt/gnome/lib/lib*so* r, /opt/gnome/lib/pango/1.4.0/modules/* r, /opt/gnome/share/icons r, /opt/gnome/share/icons/** r, /opt/gnome/bin/nautilus rux, /root r, /root/.Xauthority r, /root/.fonts.cache-1 r, /root/.realplayerrc rw, /home/*/ r, /home/*/.Xauthority r, /home/*/.fonts.cache-1 r, /home/*/.realplayerrc rw, /usr/X11R6/lib/Acrobat7/Resource/Font/* r, /usr/X11R6/lib/Acrobat7/Resource/Font/PFM/* r, /usr/lib/RealPlayer10/** r, /usr/lib/RealPlayer10/realplay.bin ixr, /usr/lib/jvm/java-1.4.2-sun-1.4.2.06/jre/lib/fonts/** r, /usr/lib/ooo-2.0/share/fonts/** r, /opt/MozillaFirefox/bin/firefox.sh pxr, /opt/MozillaFirefox/lib/firefox-bin pxr, /opt/MozillaFirefox/lib/init.d r, /usr/bin/opera pxr, /usr/share/icons r, /usr/share/icons/** r, /opt/gnome/share/pixmaps r, /opt/gnome/share/pixmaps/** r, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_quoted_1.sd0000644000175000017500000000015313502024172021506 0ustar jjjj# #=DESCRIPTION simple quoted tab expansion #=EXRESULT PASS # profile test { "/bin/alpha\tbeta" rix, } apparmor-2.13.3/parser/tst/simple_tests/file/bad_bare_file_outside.sd0000644000175000017500000000011613502024172023545 0ustar jjjj# #=DESCRIPTION bare file rule outside of a profile #=EXRESULT FAIL # file, apparmor-2.13.3/parser/tst/simple_tests/file/ok_octal_2.sd0000644000175000017500000000015613502024172021313 0ustar jjjj# #=DESCRIPTION simple quoted octal expansion #=EXRESULT PASS # profile octal { "/bin/a b \143 d e" rix, } apparmor-2.13.3/parser/tst/simple_tests/file/var1_target_ok_link_1.sd0000644000175000017500000000017413502024172023444 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { /alpha/beta rl, /gamma/* rwl, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_other_1.sd0000644000175000017500000000013513502024172021326 0ustar jjjj# #=DESCRIPTION simple other flag test #=EXRESULT PASS profile test { other /tmp/** rw, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_other_2.sd0000644000175000017500000000014713502024172021332 0ustar jjjj# #=DESCRIPTION simple deny other flag test #=EXRESULT PASS profile test { deny other /tmp/** rw, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_octal_1.sd0000644000175000017500000000013413502024172021306 0ustar jjjj# #=DESCRIPTION simple octal test #=EXRESULT PASS # profile ascii { /bin/\141bcde rix, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_deny_1.sd0000644000175000017500000000016413502024172021146 0ustar jjjj# #=DESCRIPTION A simple deny rule #=EXRESULT PASS # vim:syntax=apparmor # /usr/bin/foo { deny /usr/bin/foo r, } apparmor-2.13.3/parser/tst/simple_tests/file/bad_append_1.sd0000644000175000017500000000011613502024172021570 0ustar jjjj# #=DESCRIPTION w and a conflict #=EXRESULT FAIL # /usr/bin/foo { /a wa, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_embedded_spaces_4.sd0000644000175000017500000000014013502024172023273 0ustar jjjj#=DESCRIPTION Simple test case for embedded spaces #=EXRESULT PASS /bin/foo { /abc\ def r, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_inv_char_class.sd0000644000175000017500000000013013502024172022736 0ustar jjjj# #=DESCRIPTION carat in pathname #=EXRESULT PASS # /usr/bin/foo { /foo[^me]bar r, } apparmor-2.13.3/parser/tst/simple_tests/file/var2_target_ok_link_3.sd0000644000175000017500000000022313502024172023442 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { link subset /alpha/beta -> /foo@{var}, /foo@{var} r, } apparmor-2.13.3/parser/tst/simple_tests/file/var2_target_ok_audit_deny_link.sd0000644000175000017500000000020713502024172025427 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { audit deny link /alpha/beta -> /foo@{var}, } apparmor-2.13.3/parser/tst/simple_tests/file/var1_target_ok_link_3.sd0000644000175000017500000000021313502024172023440 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { link subset /alpha/beta -> @{var}, @{var} r, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_comma_1.sd0000644000175000017500000000012413502024172021277 0ustar jjjj# #=DESCRIPTION comma in pathname #=EXRESULT PASS # /usr/bin/foo { /foo,bar r, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_carat_2.sd0000644000175000017500000000013613502024172021301 0ustar jjjj# #=DESCRIPTION trailing carat in pathname #=EXRESULT PASS # /usr/bin/foo { /foo/bar^ r, } apparmor-2.13.3/parser/tst/simple_tests/file/var1_ok_deny_link.sd0000644000175000017500000000017013502024172022671 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { deny link @{var} -> @{var}, } apparmor-2.13.3/parser/tst/simple_tests/file/bad_embedded_0_2.sd0000644000175000017500000000023613502024172022275 0ustar jjjj# #=DESCRIPTION embedded \x00 in file path #=EXRESULT PASS # currently do NOT have semantic checks for \000 in file path # /usr/bin/foo { /foo\x00bar w, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_link_1.sd0000644000175000017500000000015713502024172021146 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # profile test { /alpha/beta rl, /gamma/* rwl, } apparmor-2.13.3/parser/tst/simple_tests/file/bad_embedded_0_3.sd0000644000175000017500000000023613502024172022276 0ustar jjjj# #=DESCRIPTION embedded \d00 in file path #=EXRESULT PASS # currently do NOT have semantic checks for \000 in file path # /usr/bin/foo { /foo\d00bar w, } apparmor-2.13.3/parser/tst/simple_tests/file/allow/0000755000175000017500000000000013502024172020063 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/file/allow/ok_comma_2.sd0000644000175000017500000000017013502024172022417 0ustar jjjj# #=DESCRIPTION comma at end of pathname #=EXRESULT PASS # vim:syntax=apparmor # /usr/bin/foo { allow "/foobar," r, } apparmor-2.13.3/parser/tst/simple_tests/file/allow/ok_mmap_1.sd0000644000175000017500000000043113502024172022254 0ustar jjjj# #=DESCRIPTION m and [uUpPi]x do not conflict #=EXRESULT PASS # vim:syntax=apparmor # /usr/bin/foo { allow /{usr/,}bin/cat mix, allow /{usr/,}bin/true mpx, allow /{usr/,}bin/false mux, allow /lib/libc.so rwlm, allow /{usr/,}bin/less mUx, allow /{usr/,}bin/more mPx, } apparmor-2.13.3/parser/tst/simple_tests/file/allow/ok_append_1.sd0000644000175000017500000000042013502024172022567 0ustar jjjj# #=DESCRIPTION test append #=EXRESULT PASS # vim:syntax=apparmor # /usr/bin/foo { allow /{usr/,}bin/cat a, allow /{usr/,}bin/true ra, allow /{usr/,}bin/false ma, allow /lib/libc.so la, allow /{usr/,}bin/less ixa, allow /{usr/,}bin/more pxa, allow /a uxa, } apparmor-2.13.3/parser/tst/simple_tests/file/allow/ok_carat_1.sd0000644000175000017500000000015713502024172022421 0ustar jjjj# #=DESCRIPTION carat in pathname #=EXRESULT PASS # vim:syntax=apparmor # /usr/bin/foo { allow /foo^bar r, } apparmor-2.13.3/parser/tst/simple_tests/file/allow/ok_3.sd0000644000175000017500000000023113502024172021242 0ustar jjjj# #=DESCRIPTION A simple successful profile #=EXRESULT PASS # vim:syntax=apparmor # /usr/bin/foo { allow /usr/bin/foo r, allow /usr/bin/blah rix, } apparmor-2.13.3/parser/tst/simple_tests/file/allow/ok_embedded_spaces_1.sd0000644000175000017500000000020513502024172024410 0ustar jjjj#=DESCRIPTION Simple test case for embedded spaces #=EXRESULT PASS # vim:syntax=apparmor /{usr/,}bin/foo { allow "/abc\ def" r, } apparmor-2.13.3/parser/tst/simple_tests/file/allow/ok_mmap_2.sd0000644000175000017500000000052413502024172022260 0ustar jjjj# #=DESCRIPTION m and [upi]x do not conflict, seperate rules #=EXRESULT PASS # vim:syntax=apparmor # /usr/bin/foo { allow /{usr/,}bin/cat rm, allow /{usr/,}bin/cat ix, allow /{usr/,}bin/true px, allow /{usr/,}bin/true m, allow /{usr/,}bin/false m, allow /{usr/,}bin/false ux, allow /lib/libc.so rwl, allow /lib/libc.so m, } apparmor-2.13.3/parser/tst/simple_tests/file/allow/ok_embedded_spaces_2.sd0000644000175000017500000000020413502024172024410 0ustar jjjj#=DESCRIPTION Simple test case for embedded spaces #=EXRESULT PASS # vim:syntax=apparmor /{usr/,}bin/foo { allow "/abc def" r, } apparmor-2.13.3/parser/tst/simple_tests/file/allow/ok_other_1.sd0000644000175000017500000000015113502024172022442 0ustar jjjj# #=DESCRIPTION simple allow other flag test #=EXRESULT PASS profile test { allow other /tmp/** rw, } apparmor-2.13.3/parser/tst/simple_tests/file/allow/ok_other_2.sd0000644000175000017500000000016513502024172022450 0ustar jjjj# #=DESCRIPTION simple audit allow other flag test #=EXRESULT PASS profile test { audit allow other /tmp/** rw, } apparmor-2.13.3/parser/tst/simple_tests/file/allow/ok_inv_char_class.sd0000644000175000017500000000016413502024172024063 0ustar jjjj# #=DESCRIPTION carat in pathname #=EXRESULT PASS # vim:syntax=apparmor # /usr/bin/foo { allow /foo[^me]bar r, } apparmor-2.13.3/parser/tst/simple_tests/file/allow/ok_comma_1.sd0000644000175000017500000000016013502024172022415 0ustar jjjj# #=DESCRIPTION comma in pathname #=EXRESULT PASS # vim:syntax=apparmor # /usr/bin/foo { allow /foo,bar r, } apparmor-2.13.3/parser/tst/simple_tests/file/allow/ok_carat_2.sd0000644000175000017500000000017113502024172022416 0ustar jjjj# #=DESCRIPTION trailing carat in pathname #=EXRESULT PASS # vim:syntax=apparmor # /usr/bin/foo { allow /foo/bar^ r, } apparmor-2.13.3/parser/tst/simple_tests/file/allow/ok_embedded_spaces_3.sd0000644000175000017500000000020013502024172024405 0ustar jjjj#=DESCRIPTION Simple test case for embedded spaces #=EXRESULT PASS # vim:syntax=apparmor "/bin/fo o" { allow "/abc def" r, } apparmor-2.13.3/parser/tst/simple_tests/file/allow/ok_lock_1.sd0000644000175000017500000000061513502024172022256 0ustar jjjj# #=DESCRIPTION k and other perms do not conflict #=EXRESULT PASS # vim:syntax=apparmor # /usr/bin/foo { allow /{usr/,}bin/a k, allow /{usr/,}bin/b rk, allow /{usr/,}bin/c wk, allow /{usr/,}bin/d ak, allow /{usr/,}bin/e lk, allow /{usr/,}bin/e mk, allow /{usr/,}bin/f pxk, allow /{usr/,}bin/g Pxk, allow /{usr/,}bin/h ixk, allow /{usr/,}bin/i uxk, allow /{usr/,}bin/j Uxk, } apparmor-2.13.3/parser/tst/simple_tests/file/allow/ok_1.sd0000644000175000017500000000016113502024172021242 0ustar jjjj# #=Description basic file rule #=EXRESULT PASS # vim:syntax=apparmor # /usr/bin/foo { allow /usr/bin/foo r, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_embedded_spaces_3.sd0000644000175000017500000000014413502024172023276 0ustar jjjj#=DESCRIPTION Simple test case for embedded spaces #=EXRESULT PASS "/bin/fo o" { "/abc def" r, } apparmor-2.13.3/parser/tst/simple_tests/file/var2_ok_link_2.sd0000644000175000017500000000021313502024172022072 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { link /foo@{var} -> /foo@{var}, /foo@{var} r, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_other_3.sd0000644000175000017500000000014313502024172021327 0ustar jjjj# #=DESCRIPTION simple other flag test #=EXRESULT PASS profile test { audit other /tmp/** rw, } apparmor-2.13.3/parser/tst/simple_tests/file/var1_src_ok_deny_link.sd0000644000175000017500000000017113502024172023541 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { deny link @{var} -> /tmp/**, } apparmor-2.13.3/parser/tst/simple_tests/file/owner/0000755000175000017500000000000013502024172020077 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/file/owner/bad_1.sd0000644000175000017500000000017313502024172021376 0ustar jjjj# #=DESCRIPTION owner is not allowed on capability rules #=EXRESULT FAIL # /usr/bin/foo { owner capability sys_admin, } apparmor-2.13.3/parser/tst/simple_tests/file/owner/ok_alternations_1.sd0000644000175000017500000000026713502024172024050 0ustar jjjj# #=Description basic file rule w/alternations #=EXRESULT PASS # /usr/bin/foo { owner /a/b/c/**{cache,data,download,/ext,fileadmin,files,images,joomla,moodledata/sessions}/** rw, } apparmor-2.13.3/parser/tst/simple_tests/file/owner/bad_5.sd0000644000175000017500000000016613502024172021404 0ustar jjjj# #=DESCRIPTION owner rules must have comma termination #=EXRESULT FAIL # /usr/bin/foo { owner /foo rw /bar rw, } apparmor-2.13.3/parser/tst/simple_tests/file/owner/bad_6.sd0000644000175000017500000000015213502024172021400 0ustar jjjj# #=DESCRIPTION owner not allowed after forward perm #=EXRESULT FAIL # /usr/bin/foo { rw owner /foo, } apparmor-2.13.3/parser/tst/simple_tests/file/owner/bad_4.sd0000644000175000017500000000014413502024172021377 0ustar jjjj# #=DESCRIPTION owner cannot follow permission #=EXRESULT FAIL # /usr/bin/foo { /foo rw owner, } apparmor-2.13.3/parser/tst/simple_tests/file/owner/bad_8.sd0000644000175000017500000000015213502024172021402 0ustar jjjj# #=DESCRIPTION owner block needs } termination #=EXRESULT FAIL # /usr/bin/foo { owner { rw foo, } apparmor-2.13.3/parser/tst/simple_tests/file/owner/bad_7.sd0000644000175000017500000000016613502024172021406 0ustar jjjj# #=DESCRIPTION owner not allowed after pathname in forward rule #=EXRESULT FAIL # /usr/bin/foo { rw /foo owner, } apparmor-2.13.3/parser/tst/simple_tests/file/owner/bad_2.sd0000644000175000017500000000015313502024172021375 0ustar jjjj# #=DESCRIPTION owner is not allowed on network rules #=EXRESULT FAIL # /usr/bin/foo { owner network, } apparmor-2.13.3/parser/tst/simple_tests/file/owner/ok_alternations_2.sd0000644000175000017500000000027413502024172024047 0ustar jjjj# #=Description basic file rule w/nested alternations #=EXRESULT PASS # /usr/bin/foo { owner /a/b/c/**{cache,data,download,/ext,file{admin,s},images,joomla,moodledata/sessions}/** rw, } apparmor-2.13.3/parser/tst/simple_tests/file/owner/bad_3.sd0000644000175000017500000000014413502024172021376 0ustar jjjj# #=DESCRIPTION owner can not follow path name #=EXRESULT FAIL # /usr/bin/foo { /foo owner rw, } apparmor-2.13.3/parser/tst/simple_tests/file/owner/ok_1.sd0000644000175000017500000000037113502024172021261 0ustar jjjj# #=DESCRIPTION test owner flag for file rules #=EXRESULT PASS # /usr/bin/foo { owner /foo rw, owner /foo/** rw, owner rw /bar, owner rw /bar/**, owner { /one rw, /one/** rw, rw /two, rw /two/**, } owner { } } apparmor-2.13.3/parser/tst/simple_tests/file/ok_alternations_2.sd0000644000175000017500000000026613502024172022716 0ustar jjjj# #=Description basic file rule w/nested alternations #=EXRESULT PASS # /usr/bin/foo { /a/b/c/**{cache,data,download,/ext,file{admin,s},images,joomla,moodledata/sessions}/** rw, } apparmor-2.13.3/parser/tst/simple_tests/file/var2_src_ok_audit_deny_link.sd0000644000175000017500000000020313502024172024724 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { audit deny link /foo@{var} -> /tmp/**, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_quoted_5.sd0000644000175000017500000000016113502024172021511 0ustar jjjj# #=DESCRIPTION simple quoted backslash expansion #=EXRESULT PASS # profile test { "/bin/alpha\\beta" rix, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_lock_1.sd0000644000175000017500000000035013502024172021134 0ustar jjjj# #=DESCRIPTION k and other perms do not conflict #=EXRESULT PASS # /usr/bin/foo { /bin/a k, /bin/b rk, /bin/c wk, /bin/d ak, /bin/e lk, /bin/e mk, /bin/f pxk, /bin/g Pxk, /bin/h ixk, /bin/i uxk, /bin/j Uxk, } apparmor-2.13.3/parser/tst/simple_tests/file/var1_ok_audit_deny_link.sd0000644000175000017500000000017613502024172024065 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { audit deny link @{var} -> @{var}, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_2.sd0000644000175000017500000000020213502024172020121 0ustar jjjj# #=Description basic uppercase permission file rule (should emit warning) #=EXRESULT PASS # /usr/bin/foo { /usr/bin/foo RWM, } apparmor-2.13.3/parser/tst/simple_tests/file/stacking_ok_1.sd0000644000175000017500000000016413502024172022012 0ustar jjjj# #=Description basic file exec rule with stacking target #=EXRESULT PASS # /usr/bin/foo { /bin/bar px -> &baz, } apparmor-2.13.3/parser/tst/simple_tests/file/var2_ok_link_1.sd0000644000175000017500000000017313502024172022076 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { /foo@{var} rl, /gamma/* rwl, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_1.sd0000644000175000017500000000012513502024172020124 0ustar jjjj# #=Description basic file rule #=EXRESULT PASS # /usr/bin/foo { /usr/bin/foo r, } apparmor-2.13.3/parser/tst/simple_tests/file/var2_target_ok_link_2.sd0000644000175000017500000000021413502024172023441 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # @{var}=/test profile test { link /alpha/beta -> /foo@{var}, /foo@{var} r, } apparmor-2.13.3/parser/tst/simple_tests/file/ok_audit_deny_link.sd0000644000175000017500000000016713502024172023134 0ustar jjjj# #=DESCRIPTION simple link access test #=EXRESULT PASS # profile test { audit deny link /alpha/beta -> /tmp/**, } apparmor-2.13.3/parser/tst/simple_tests/signal/0000755000175000017500000000000013502024172017303 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/signal/ok_03.sd0000644000175000017500000000015113502024172020543 0ustar jjjj# #=Description basic allow signal all rule #=EXRESULT PASS # /usr/bin/signal-test { allow signal, } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_06.sd0000644000175000017500000000027513502024172020555 0ustar jjjj# #=Description basic signal write/send rules #=EXRESULT PASS # /usr/bin/signal-test { signal w, } /usr/bin/signal-test2 { signal write, } /usr/bin/signal-test3 { signal send, } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_01.sd0000644000175000017500000000013513502024172020543 0ustar jjjj# #=Description basic signal all rule #=EXRESULT PASS # /usr/bin/signal-test { signal, } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_21.sd0000644000175000017500000000075713502024172020557 0ustar jjjj# #=Description basic signal w/multiple signal set rule #=EXRESULT PASS # /usr/bin/signal-test1 { audit signal send set=hup set=int set=quit set=ill set=trap, deny signal receive set=abrt set=bus set=fpe set=kill set=usr1 set=segv, allow signal receive set=usr2 set=pipe set=alrm set=term set=stkflt, audit allow signal set=chld set=cont set=stop set=stp set=ttin, audit deny signal set=(ttou, urg) set=(xcpu xfsz vtalrm , prof) set=winch set=io set=pwr set=sys set=emt set=exists, } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_11.sd0000644000175000017500000000216713502024172020553 0ustar jjjj# #=Description basic signal w/specific signals rule #=EXRESULT PASS # /usr/bin/signal-test1 { signal r set=(hup), signal rw set=(int), signal receive set=(quit), signal read set=(ill), signal write set=(trap), signal send set=(abrt), allow signal set=(bus), audit allow signal set=(fpe), deny signal set=(kill), audit deny signal set=(usr1), allow signal (send, receive) set=(segv), audit allow signal (r, write) set=(usr2), deny signal (send) set=(pipe), signal w set=(alrm), audit signal set=(term), audit signal (receive) set=(stkflt), audit deny signal (send, receive) set=(chld), signal read set=(cont), signal write set=(stop), signal rw set=(stp), signal send set=(ttin), signal receive set=(ttou), signal (send receive) set=(urg), signal (read write) set=(xcpu), deny signal (send) set=(xfsz), deny signal (send receive) set=(vtalrm), audit signal (send) set=(prof), audit signal (receive) set=(winch), audit signal (send receive) set=(io), allow signal set=(pwr), allow signal (r) set=(sys), allow signal (w, write send) set=(emt), allow signal (r w) set=(exists), } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_01.sd0000644000175000017500000000020713502024172020660 0ustar jjjj# #=Description basic signal no parens permissions rule #=EXRESULT FAIL # /usr/bin/signal-test { signal read write send receive, } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_04.sd0000644000175000017500000000015113502024172020544 0ustar jjjj# #=Description basic audit signal all rule #=EXRESULT PASS # /usr/bin/signal-test { audit signal, } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_05.sd0000644000175000017500000000020313502024172020660 0ustar jjjj# #=Description basic signal set= inside parens #=EXRESULT FAIL # /usr/bin/signal-test { signal send set=(hup segv set=int), } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_14.sd0000644000175000017500000000016013502024172020662 0ustar jjjj# #=DESCRIPTION simple bad rtmin value test #=EXRESULT FAIL # /usr/bin/signal-test { signal set=rtmin+-99, } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_02.sd0000644000175000017500000000014713502024172020547 0ustar jjjj# #=Description basic deny signal all rule #=EXRESULT PASS # /usr/bin/signal-test { deny signal, } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_19.sd0000644000175000017500000000015613502024172020674 0ustar jjjj# #=DESCRIPTION simple signal w/bad option #=EXRESULT FAIL # /usr/bin/signal-test { signal options=(ro), } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_20.sd0000644000175000017500000000014213502024172020657 0ustar jjjj# #=DESCRIPTION simple signal w/bad perm #=EXRESULT FAIL # /usr/bin/signal-test { signal mr, } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_16.sd0000644000175000017500000000044213502024172020552 0ustar jjjj# #=Description basic signal w/multiple var names rule #=EXRESULT PASS # @{SHELLS}=/bin/bash /bin/dash /bin/tcsh /usr/bin/signal-test1 { signal peer=@{SHELLS}, } /usr/bin/signal-test2 { signal (send) peer=@{SHELLS}, } /usr/bin/signal-test3 { signal (receive) peer=@{SHELLS}, } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_10.sd0000644000175000017500000000321113502024172020541 0ustar jjjj# #=Description basic signal w/specific signals rule #=EXRESULT PASS # /usr/bin/signal-test1 { signal set=(hup), } /usr/bin/signal-test2 { signal set=(int), } /usr/bin/signal-test3 { signal set=(quit), } /usr/bin/signal-test4 { signal set=(ill), } /usr/bin/signal-test5 { signal set=(trap), } /usr/bin/signal-test6 { signal set=(abrt), } /usr/bin/signal-test7 { signal set=(bus), } /usr/bin/signal-test8 { signal set=(fpe), } /usr/bin/signal-test9 { signal set=(kill), } /usr/bin/signal-test10 { signal set=(usr1), } /usr/bin/signal-test11 { signal set=(segv), } /usr/bin/signal-test12 { signal set=(usr2), } /usr/bin/signal-test13 { signal set=(pipe), } /usr/bin/signal-test14 { signal set=(alrm), } /usr/bin/signal-test15 { signal set=(term), } /usr/bin/signal-test16 { signal set=(stkflt), } /usr/bin/signal-test17 { signal set=(chld), } /usr/bin/signal-test18 { signal set=(cont), } /usr/bin/signal-test19 { signal set=(stop), } /usr/bin/signal-test20 { signal set=(stp), } /usr/bin/signal-test21 { signal set=(ttin), } /usr/bin/signal-test22 { signal set=(ttou), } /usr/bin/signal-test23 { signal set=(urg), } /usr/bin/signal-test24 { signal set=(xcpu), } /usr/bin/signal-test25 { signal set=(xfsz), } /usr/bin/signal-test26 { signal set=(vtalrm), } /usr/bin/signal-test27 { signal set=(prof), } /usr/bin/signal-test28 { signal set=(winch), } /usr/bin/signal-test29 { signal set=(io), } /usr/bin/signal-test30 { signal set=(pwr), } /usr/bin/signal-test31 { signal set=(sys), } /usr/bin/signal-test32 { signal set=(emt), } /usr/bin/signal-test33 { signal set=(exists), } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_07.sd0000644000175000017500000000036313502024172020554 0ustar jjjj# #=Description basic signal mixed send/receive rules #=EXRESULT PASS # /usr/bin/signal-test { signal r, signal rw, } /usr/bin/signal-test2 { signal read, signal write, } /usr/bin/signal-test3 { signal send, signal receive, } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_12.sd0000644000175000017500000000234713502024172020554 0ustar jjjj# #=Description basic signal w/multiple signal set rule #=EXRESULT PASS # /usr/bin/signal-test1 { signal set=(hup, int, quit, ill, trap, abrt, bus, fpe, kill, usr1, segv, usr2, pipe, alrm, term, stkflt, chld, cont, stop, stp, ttin, ttou, urg, xcpu, xfsz, vtalrm, prof, winch, io, pwr, sys, emt, exists), } /usr/bin/signal-test2 { signal set=(hup int quit ill trap abrt bus fpe kill usr1 segv usr2 pipe alrm term stkflt chld cont stop stp ttin ttou urg xcpu xfsz vtalrm prof winch io pwr sys emt exists), } /usr/bin/signal-test3 { signal send set=(hup, int, quit, ill, trap, abrt, bus, fpe, kill, usr1, segv, usr2, pipe, alrm, term, stkflt, chld, cont, stop, stp, ttin, ttou, urg, xcpu, xfsz, vtalrm, prof, winch, io, pwr, sys, emt, exists), } /usr/bin/signal-test4 { signal (send, receive) set=(hup, int, quit, ill, trap, abrt, bus, fpe, kill, usr1, segv, usr2, pipe, alrm, term, stkflt, chld, cont, stop, stp, ttin, ttou, urg, xcpu, xfsz, vtalrm, prof, winch, io, pwr, sys, emt, exists), } /usr/bin/signal-test5 { signal (send receive) set=(hup, int, quit, ill, trap, abrt, bus, fpe, kill, usr1, segv, usr2, pipe, alrm, term, stkflt, chld, cont, stop, stp, ttin, ttou, urg, xcpu, xfsz, vtalrm, prof, winch, io, pwr, sys, emt, exists), } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_09.sd0000644000175000017500000000073513502024172020561 0ustar jjjj# #=Description basic signal mixed send/receive w/modifiers rules #=EXRESULT PASS # /usr/bin/signal-test { deny signal (r), audit signal (rw), } /usr/bin/signal-test2 { allow signal (r, w), audit signal (read, write), } /usr/bin/signal-test3 { audit deny signal (send, receive), } /usr/bin/signal-test4 { audit allow signal (r send, receive, write, rw, send), deny signal r, } /usr/bin/signal-test5 { deny signal (r send,,,, receive,write,rw, send), } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_09.sd0000644000175000017500000000015613502024172020673 0ustar jjjj# #=Description basic signal bad signal #=EXRESULT FAIL # /usr/bin/signal-test { signal send set=nohup, } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_07.sd0000644000175000017500000000014613502024172020670 0ustar jjjj# #=Description basic signal bad perm #=EXRESULT FAIL # /usr/bin/signal-test { signal tracedby, } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_08.sd0000644000175000017500000000063113502024172020553 0ustar jjjj# #=Description basic signal mixed send/receive rules #=EXRESULT PASS # /usr/bin/signal-test { signal (r), signal (rw), } /usr/bin/signal-test2 { signal (r, w), signal (read, write), } /usr/bin/signal-test3 { signal (send, receive), } /usr/bin/signal-test4 { signal (r send, receive, write, rw, send), signal r, } /usr/bin/signal-test5 { signal (r send,,,, receive,write,rw, send), } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_15.sd0000644000175000017500000000020613502024172020547 0ustar jjjj# #=Description basic signal w/implicit profile name rule #=EXRESULT PASS # /usr/bin/signal-test { signal peer=@{profile_name}, } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_21.sd0000644000175000017500000000016313502024172020663 0ustar jjjj# #=Description signal w/bad regex expansion #=EXRESULT FAIL # /usr/bin/signal-test { signal peer={/bin/true, } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_12.sd0000644000175000017500000000015513502024172020664 0ustar jjjj# #=Description basic bad signal 'lost' #=EXRESULT FAIL # /usr/bin/signal-test { signal send set=lost, } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_18.sd0000644000175000017500000000014413502024172020670 0ustar jjjj# #=DESCRIPTION simple bare peer keyword #=EXRESULT FAIL # /usr/bin/signal-test { signal peer, } apparmor-2.13.3/parser/tst/simple_tests/signal/rtsig_01.sd0000644000175000017500000000016713502024172021267 0ustar jjjj# #=DESCRIPTION simple rtsig test #=EXRESULT PASS # /usr/bin/signal-test { signal set=(rtmin+30 rtmin+0 rtmin+1), } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_17.sd0000644000175000017500000000014213502024172020665 0ustar jjjj# #=DESCRIPTION simple bare set keyword #=EXRESULT FAIL # /usr/bin/signal-test { signal set, } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_outside_01.sd0000644000175000017500000000011713502024172022414 0ustar jjjj# #=Description signal rule outside of a profile #=EXRESULT FAIL # signal, apparmor-2.13.3/parser/tst/simple_tests/signal/bad_04.sd0000644000175000017500000000023713502024172020666 0ustar jjjj# #=Description basic signal bad peer #=EXRESULT FAIL # /usr/bin/signal-test { signal (read write send receive) set=(hup, int) peer=/bin/bash /bin/dash, } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_19.sd0000644000175000017500000000066613502024172020565 0ustar jjjj# #=Description basic signal w/multiple signal set rule #=EXRESULT PASS # /usr/bin/signal-test1 { signal set=hup set=int set=quit set=ill set=trap set=abrt set=bus set=fpe set=kill set=usr1 set=segv set=usr2 set=pipe set=alrm set=term set=stkflt set=chld set=cont set=stop set=stp set=ttin set=ttou set=urg set=xcpu set=xfsz set=vtalrm set=prof set=winch set=io set=pwr set=sys set=emt set=exists, } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_14.sd0000644000175000017500000000015713502024172020553 0ustar jjjj# #=Description basic signal w/peer rule #=EXRESULT PASS # /usr/bin/signal-test { signal peer=/bin/init, } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_20.sd0000644000175000017500000000037513502024172020552 0ustar jjjj# #=Description basic signal w/multiple signal set rule #=EXRESULT PASS # /usr/bin/signal-test { signal set=(hup int quit ill trap abrt) set=(bus,fpe,,,kill,usr1) set=segv set=usr2 set=pipe set=alrm set=term set=stkflt set=chld, } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_18.sd0000644000175000017500000000310713502024172020555 0ustar jjjj# #=Description basic signal w/specific signals rule #=EXRESULT PASS # /usr/bin/signal-test1 { signal set=hup, } /usr/bin/signal-test2 { signal set=int, } /usr/bin/signal-test3 { signal set=quit, } /usr/bin/signal-test4 { signal set=ill, } /usr/bin/signal-test5 { signal set=trap, } /usr/bin/signal-test6 { signal set=abrt, } /usr/bin/signal-test7 { signal set=bus, } /usr/bin/signal-test8 { signal set=fpe, } /usr/bin/signal-test9 { signal set=kill, } /usr/bin/signal-test10 { signal set=usr1, } /usr/bin/signal-test11 { signal set=segv, } /usr/bin/signal-test12 { signal set=usr2, } /usr/bin/signal-test13 { signal set=pipe, } /usr/bin/signal-test14 { signal set=alrm, } /usr/bin/signal-test15 { signal set=term, } /usr/bin/signal-test16 { signal set=stkflt, } /usr/bin/signal-test17 { signal set=chld, } /usr/bin/signal-test18 { signal set=cont, } /usr/bin/signal-test19 { signal set=stop, } /usr/bin/signal-test20 { signal set=stp, } /usr/bin/signal-test21 { signal set=ttin, } /usr/bin/signal-test22 { signal set=ttou, } /usr/bin/signal-test23 { signal set=urg, } /usr/bin/signal-test24 { signal set=xcpu, } /usr/bin/signal-test25 { signal set=xfsz, } /usr/bin/signal-test26 { signal set=vtalrm, } /usr/bin/signal-test27 { signal set=prof, } /usr/bin/signal-test28 { signal set=winch, } /usr/bin/signal-test29 { signal set=io, } /usr/bin/signal-test30 { signal set=pwr, } /usr/bin/signal-test31 { signal set=sys, } /usr/bin/signal-test32 { signal set=emt, } /usr/bin/signal-test33 { signal set=exists, } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_06.sd0000644000175000017500000000017513502024172020671 0ustar jjjj# #=Description basic signal bad perm #=EXRESULT FAIL # /usr/bin/signal-test { signal (read write send receive trace), } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_13.sd0000644000175000017500000000015713502024172020667 0ustar jjjj# #=DESCRIPTION simple bad rtmin value test #=EXRESULT FAIL # /usr/bin/signal-test { signal set=rtmin+33, } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_05.sd0000644000175000017500000000027113502024172020550 0ustar jjjj# #=Description basic signal read rules #=EXRESULT PASS # /usr/bin/signal-test { signal r, } /usr/bin/signal-test2 { signal read, } /usr/bin/signal-test3 { signal receive, } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_02.sd0000644000175000017500000000022113502024172020655 0ustar jjjj# #=Description basic signal no parens for signals #=EXRESULT FAIL # /usr/bin/signal-test { signal (read write send receive) set=stop stp, } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_03.sd0000644000175000017500000000022113502024172020656 0ustar jjjj# #=Description basic signal no parens for signals #=EXRESULT FAIL # /usr/bin/signal-test { signal (read write send receive) set=hup, int, } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_16.sd0000644000175000017500000000016013502024172020664 0ustar jjjj# #=DESCRIPTION simple bad 'in' keyword #=EXRESULT FAIL # /usr/bin/signal-test { signal set in (hup stop), } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_13.sd0000644000175000017500000000241713502024172020553 0ustar jjjj# #=Description basic signal w/multiple signal set rule #=EXRESULT PASS # /usr/bin/signal-test1 { audit signal set=(hup, int, quit, ill, trap, abrt, bus, fpe, kill, usr1, segv, usr2, pipe, alrm, term, stkflt, chld, cont, stop, stp, ttin, ttou, urg, xcpu, xfsz, vtalrm, prof, winch, io, pwr, sys, emt, exists), } /usr/bin/signal-test2 { deny signal set=(hup int quit ill trap abrt bus fpe kill usr1 segv usr2 pipe alrm term stkflt chld cont stop stp ttin ttou urg xcpu xfsz vtalrm prof winch io pwr sys emt exists), } /usr/bin/signal-test3 { allow signal send set=(hup, int, quit, ill, trap, abrt, bus, fpe, kill, usr1, segv, usr2, pipe, alrm, term, stkflt, chld, cont, stop, stp, ttin, ttou, urg, xcpu, xfsz, vtalrm, prof, winch, io, pwr, sys, emt, exists), } /usr/bin/signal-test4 { audit allow signal (send, receive) set=(hup, int, quit, ill, trap, abrt, bus, fpe, kill, usr1, segv, usr2, pipe, alrm, term, stkflt, chld, cont, stop, stp, ttin, ttou, urg, xcpu, xfsz, vtalrm, prof, winch, io, pwr, sys, emt, exists), } /usr/bin/signal-test5 { audit deny signal (send receive) set=(hup, int, quit, ill, trap, abrt, bus, fpe, kill, usr1, segv, usr2, pipe, alrm, term, stkflt, chld, cont, stop, stp, ttin, ttou, urg, xcpu, xfsz, vtalrm, prof, winch, io, pwr, sys, emt, exists), } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_11.sd0000644000175000017500000000016413502024172020663 0ustar jjjj# #=Description basic signal bad signal #=EXRESULT FAIL # /usr/bin/signal-test { signal send set=(hup nohup), } apparmor-2.13.3/parser/tst/simple_tests/signal/rtsig_02.sd0000644000175000017500000000021413502024172021261 0ustar jjjj# #=DESCRIPTION simple rtsig test #=EXRESULT PASS # /usr/bin/signal-test { signal set=(rtmin+20) set=rtmin+5 set=(rtmin+001, rtmin+8), } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_10.sd0000644000175000017500000000016013502024172020656 0ustar jjjj# #=Description basic signal bad signal #=EXRESULT FAIL # /usr/bin/signal-test { signal send set=(nohup), } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_15.sd0000644000175000017500000000020413502024172020662 0ustar jjjj# #=DESCRIPTION simple bad rtmin value test #=EXRESULT FAIL # /usr/bin/signal-test { signal set=hup set=stop set=bad set=ttin, } apparmor-2.13.3/parser/tst/simple_tests/signal/ok_17.sd0000644000175000017500000000055113502024172020554 0ustar jjjj# #=Description basic signal w/regex peer #=EXRESULT PASS # /usr/bin/signal-test1 { signal (send) peer=/{**/,}bin/{sh,true}, } /usr/bin/signal-test2 { signal (receive) set=(fpe stop) peer=/sbin/{init,systend,upstart}, } /usr/bin/signal-test3 { audit deny signal receive set=(stop, int, usr1, usr2) peer=/**.{py,pl,rb}, signal receive set=(segv), } apparmor-2.13.3/parser/tst/simple_tests/signal/bad_08.sd0000644000175000017500000000020113502024172020661 0ustar jjjj# #=Description basic signal multiple peer entries #=EXRESULT FAIL # /usr/bin/signal-test { signal send peer=foo peer=bar, } apparmor-2.13.3/parser/tst/simple_tests/vars/0000755000175000017500000000000013502024172017001 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/vars/vars_file_evaluation_10.sd0000644000175000017500000000021513502024172024030 0ustar jjjj#=DESCRIPTION some simple expansions within file rules #=EXRESULT PASS @{FOO} = /foo /bar /baz /biff /usr/bin/foo { @{FOO}.+=/.foo/* r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_file_evaluation_3.sd0000644000175000017500000000024013502024172023750 0ustar jjjj#=DESCRIPTION some simple expansions within file rules #=EXRESULT PASS @{FOO} = foo bar baz biff @{BAR} = *.jpg /usr/bin/foo { /home/@{FOO}/.foo/@{BAR} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_bad_6.sd0000644000175000017500000000020613502024172021335 0ustar jjjj#=DESCRIPTION list variables need leading @ symbol #=EXRESULT FAIL {FOO} = /foo /bar /baz /biff /usr/bin/foo { /@{FOO}/.foo/* r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_21.sd0000644000175000017500000000014713502024172023330 0ustar jjjj#=DESCRIPTION var in hat name #=EXRESULT PASS @{FOO}=bar profile /does/not/exist { ^@{FOO} { } } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_simple_assignment_11.sd0000644000175000017500000000017413502024172024410 0ustar jjjj#=DESCRIPTION Test for continuation onto newline #=EXRESULT PASS @{FOO} = blah \\ @{BAR} = baz /bin/true { /@{BAR} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_07.sd0000644000175000017500000000037113502024172023333 0ustar jjjj#=DESCRIPTION profiles declared with the profile keyword can begin with var #=EXRESULT FAIL #=TODO # This test needs check on @{FOO} attachment having leading / post var expansion @{FOO}=bar profile /does/not/exist @{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_alternation_4.sd0000644000175000017500000000023713502024172023131 0ustar jjjj#=DESCRIPTION variable w/part of an alternation included #=EXRESULT PASS @{BAR}=bar,baz,blort} /does/not/exist { /does/not/{exist,notexist@{BAR}/meep r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_alternation_5.sd0000644000175000017500000000023613502024172023131 0ustar jjjj#=DESCRIPTION variable w/part of an alternation included #=EXRESULT PASS @{BAR}=bar,baz,blort /does/not/exist { /does/not/{exist@{BAR}notexist}/meep r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_08.sd0000644000175000017500000000037513502024172023340 0ustar jjjj#=DESCRIPTION profiles declared with the profile keyword can begin with var #=EXRESULT FAIL #=TODO # This test needs check on @{FOO} attachment having leading / post var expansion @{FOO}=bar baz profile /does/not/exist @{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_simple_assignment_8.sd0000644000175000017500000000012013502024172024325 0ustar jjjj#=DESCRIPTION invalid characters in variable names #=EXRESULT FAIL @{_} = blah apparmor-2.13.3/parser/tst/simple_tests/vars/vars_recursion_2.sd0000644000175000017500000000020613502024172022614 0ustar jjjj#=DESCRIPTION recursive set definitions -- two variables #=EXRESULT FAIL @{FOO}=@{BAR} @{BAR}=@{FOO} /bin/foo { /home/@{FOO} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_11.sd0000644000175000017500000000030513502024172023323 0ustar jjjj#=DESCRIPTION profiles declared with the profile keyword have var and var attachment #=EXRESULT PASS @{FOO}=/bar /baz @{BAR}=baz foo profile /does/not/exist@{BAR} @{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_file_evaluation_7.sd0000644000175000017500000000021313502024172023754 0ustar jjjj#=DESCRIPTION some simple expansions within file rules #=EXRESULT FAIL @{FOO} = /foo /bar /baz /biff /usr/bin/foo { @{FOO}=/.foo/* r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_22.sd0000644000175000017500000000035413502024172023331 0ustar jjjj#=DESCRIPTION all attachment expansions must start with / #=EXRESULT FAIL #=TODO # This test needs check on @{FOO} attachment having leading / post var expansion @{FOO}=/bar baz profile /does/not/exist @{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_19.sd0000644000175000017500000000016613502024172023340 0ustar jjjj#=DESCRIPTION var in sub profile name #=EXRESULT PASS @{FOO}=bar profile /does/not/exist { profile @{FOO} { } } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_10.sd0000644000175000017500000000042313502024172021620 0ustar jjjj#=DESCRIPTION reference variables in dbus rules, var containing alternation #=EXRESULT PASS @{BUSES}=session system @{TLDS}=com org @{MEMBERS}={Get,Set} /does/not/exist { dbus (send, receive) bus=@{BUSES} path=/@{TLDS}/foo member=@{MEMBERS}.bar, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_stress_01.sd0000644000175000017500000000050713502024172022211 0ustar jjjj#=DESCRIPTION stress test (2828 items, 676 unique) #=EXRESULT PASS @{FOO}=a b c d e f g h i j k l m n o p q r s t u v w x y z @{BAR}=a b c d e f g h i j k l m n o p q r s t u v w x y z @{BAZ}=a b c d e f g h i j k l m n o p q r s t u v w x y z @{FBB}=@{FOO}/@{BAR} @{BAR}/@{BAZ} @{FOO}/@{BAZ} /bin/foo { /home/@{FBB} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_26.sd0000644000175000017500000000026013502024172023331 0ustar jjjj#=DESCRIPTION reference variables is null #=EXRESULT FAIL #needs post var expansion check that variable contained a value @{FOO}= profile bar @{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_09.sd0000644000175000017500000000023713502024172023336 0ustar jjjj#=DESCRIPTION reference variables in name and attachment #=EXRESULT PASS @{FOO}=bar @{BAR}=baz profile /does/not@{BAR} /exist@{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_bad_trailing_comma_1.sd0000644000175000017500000000031013502024172024371 0ustar jjjj#=DESCRIPTION trailing commas should trigger an error #=EXRESULT FAIL @{LIBVIRT} = libvirt, /does/not/exist { change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_stress_02.sd0000644000175000017500000000075113502024172022213 0ustar jjjj#=DESCRIPTION stress test (8112 items, 2704 unique) #=EXRESULT PASS @{FOO}=a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z @{BAR}=a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z @{BAZ}=a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z @{FBB}=@{FOO}/@{BAR} @{BAR}/@{BAZ} @{FOO}/@{BAZ} /bin/foo { /usr/share/@{FBB} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_bad_add_assignment_1.sd0000644000175000017500000000024513502024172024373 0ustar jjjj#=DESCRIPTION can't additional assign to variables without initial assign #=EXRESULT FAIL @{FOO} += @{BAZ} @{BAZ} = @{BAR} @{BAR} = 2006 /bin/foo { /@{FOO} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_24.sd0000644000175000017500000000016313502024172023331 0ustar jjjj#=DESCRIPTION reference variables is null #=EXRESULT FAIL @{FOO}= /does/not/exist@{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_13.sd0000644000175000017500000000037213502024172023331 0ustar jjjj#=DESCRIPTION reference variables that are the profile name and attachment #=EXRESULT FAIL #=TODO # This test needs check on @{FOO} attachment having leading / post var expansion @{FOO}=bar @{BAR}=baz profile @{BAR} @{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_bad_3.sd0000644000175000017500000000031013502024172021326 0ustar jjjj#=DESCRIPTION garbage should trigger an error #=EXRESULT FAIL @{LIBVIRT} = lib!virt libfail /does/not/exist { change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_04.sd0000644000175000017500000000022513502024172023326 0ustar jjjj#=DESCRIPTION profiles declared with the profile keyword can begin with var #=EXRESULT PASS @{FOO}=bar baz profile @{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_simple_assignment_1.sd0000644000175000017500000000011113502024172024316 0ustar jjjj#=DESCRIPTION simple set variable assignment #=EXRESULT PASS @{FOO}=bar apparmor-2.13.3/parser/tst/simple_tests/vars/vars_assignment_reference_1.sd0000644000175000017500000000016713502024172024776 0ustar jjjj#=DESCRIPTION set variable assignment using set variable as rvalue #=EXRESULT PASS @{FOO}=bar baz @{BAR}=${FOO} blort apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_bad_02.sd0000644000175000017500000000021313502024172022424 0ustar jjjj# #=DESCRIPTION missing reference variable in dbus name modifier #=EXRESULT FAIL # /does/not/exist { dbus (bind) name=@{MISSING_VAR}, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_6.sd0000644000175000017500000000030613502024172021545 0ustar jjjj#=DESCRIPTION reference variables in dbus rules, with name #=EXRESULT PASS @{FOO}=bar baz @{BAR}=@{FOO} blort /does/not/exist { dbus (bind) bus=session name="com.@{BAR}.@{FOO}", } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_file_evaluation_16.sd0000644000175000017500000000024113502024172024035 0ustar jjjj#=DESCRIPTION simple expansions within file rules with underscore variable #=EXRESULT PASS @{F_OO} = /foo /bar /baz /biff /usr/bin/foo { /@{F_OO}/.foo/* r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_auto_profile_name_05.sd0000644000175000017500000000117213502024172024361 0ustar jjjj#=DESCRIPTION reference auto profile_name variable in rules w/hats #=EXRESULT PASS profile idf3s2A6GX8vrk /simple/profile { /test/profile rix, /run/@{profile_name}/tmp rwk, ^spork { owner /tmp/* r, /spork/@{profile_name}/** rw, } ^spelunkk { owner /tmp/* r, /spelunk/@{profile_name}/** rw, } } profile LzdZb9bKTMN6y /not/simple/profile { /test/profile rix, /run/@{profile_name}/tmp rwk, ^spork { owner /tmp/* r, /run/@{profile_name}/** rw, } ^spelunkk { owner /tmp/* r, /run/@{profile_name}/** rw, } ^spry { owner /tmp/* r, /run/@{profile_name}/** rw, } } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_alternation_1.sd0000644000175000017500000000027413502024172023127 0ustar jjjj#=DESCRIPTION reference variables in rules that also have alternations #=EXRESULT PASS @{FOO}=bar baz @{BAR}=@{FOO} blort /does/not/exist { /does/not/{exist,notexist}/blah/@{BAR} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_file_evaluation_6.sd0000644000175000017500000000021213502024172023752 0ustar jjjj#=DESCRIPTION some simple expansions within file rules #=EXRESULT PASS @{FOO} = /foo /bar /baz /biff /usr/bin/foo { @{FOO}/.foo/* r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_file_evaluation_14.sd0000644000175000017500000000021413502024172024033 0ustar jjjj#=DESCRIPTION some simple expansions within file rules #=EXRESULT PASS @{FOO} = /foo /bar /baz /biff /usr/bin/foo { /@{FOO}+/.foo/* r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_18.sd0000644000175000017500000000015213502024172023332 0ustar jjjj#=DESCRIPTION var in hat name #=EXRESULT PASS @{FOO}=bar profile /does/not/exist { ^foo@{FOO} { } } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_bad_trailing_garbage_1.sd0000644000175000017500000000031113502024172024666 0ustar jjjj#=DESCRIPTION trailing garbage should trigger an error #=EXRESULT FAIL @{LIBVIRT} = libvirt" /does/not/exist { change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_simple_assignment_14.sd0000644000175000017500000000032413502024172024410 0ustar jjjj#=DESCRIPTION quoted commas should not trigger an error #=EXRESULT PASS @{LIBVIRT} = "libvirt, libtriv" /does/not/exist { change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_12.sd0000644000175000017500000000044613502024172023332 0ustar jjjj#=DESCRIPTION profiles declared with the profile keyword can expand var and have var attachment #=EXRESULT FAIL #=TODO # This test needs check on @{FOO} attachment having leading / post var expansion @{FOO}=bar baz @{BAR}=baz foo profile /does/not/exist@{BAR} @{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_15.sd0000644000175000017500000000040313502024172023326 0ustar jjjj#=DESCRIPTION profiles declared with the profile keyword can begin with var #=EXRESULT FAIL #=TODO # This test needs check on @{FOO} attachment having leading / post var expansion @{FOO}=bar baz @{BAR}=baz foo profile @{BAR} @{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_bad_trailing_comma_3.sd0000644000175000017500000000032113502024172024375 0ustar jjjj#=DESCRIPTION trailing commas should trigger an error #=EXRESULT FAIL @{LIBVIRT} = libvirt, libtriv, /does/not/exist { change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_simple_assignment_5.sd0000644000175000017500000000016013502024172024326 0ustar jjjj#=DESCRIPTION set var to one value, empty string #=EXRESULT PASS @{FOO}="" /bin/foo { @{FOO}/bin/foo rix, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_3.sd0000644000175000017500000000034613502024172021546 0ustar jjjj#=DESCRIPTION reference variables in dbus rules, bus fields #=EXRESULT PASS @{BUSES}=session system accessability choochoo /does/not/exist { dbus (send) bus=@{BUSES} path="/com/canonical/hud/applications/baz", } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_auto_profile_name_02.sd0000644000175000017500000000024213502024172024353 0ustar jjjj#=DESCRIPTION reference auto profile_name variable in rules #=EXRESULT PASS profile /a/test/profile { /a/test/profile rix, /var/@{profile_name}/tmp rwk, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_1.sd0000644000175000017500000000032013502024172021534 0ustar jjjj#=DESCRIPTION reference variables in dbus rules #=EXRESULT PASS @{FOO}=bar baz @{BAR}=@{FOO} blort /does/not/exist { dbus (send) bus=session path="/com/canonical/hud/applications/@{BAR}", } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_23.sd0000644000175000017500000000020013502024172023320 0ustar jjjj#=DESCRIPTION reference variables in profile name is undefined #=EXRESULT FAIL /does/not/exist@{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_4.sd0000644000175000017500000000043513502024172021546 0ustar jjjj#=DESCRIPTION reference variables in dbus rules, members #=EXRESULT PASS @{MEMBERS}=blurt blirt @{BAR} @{BAR}=@{FOO} blort @{FOO}=bink bank bonk blurry* /does/not/exist { dbus (send) bus=session member=@{MEMBERS} path="/com/canonical/hud/applications/biff", } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_2.sd0000644000175000017500000000042113502024172021537 0ustar jjjj#=DESCRIPTION reference variables in dbus rules, interfaces #=EXRESULT PASS @{ORGS}=freedesktop ubuntu gnome kde /does/not/exist { dbus (receive) bus=accessibility interface=org.@{ORGS}.DBus.Properties path="/com/canonical/hud/applications/bar", } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_bad_4.sd0000644000175000017500000000022413502024172021333 0ustar jjjj#=DESCRIPTION don't accept variables with leading underscores #=EXRESULT FAIL @{_FOO} = /foo /bar /baz /biff /usr/bin/foo { /@{_FOO}/.foo/* r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_simple_assignment_3.sd0000644000175000017500000000015113502024172024324 0ustar jjjj#=DESCRIPTION undefined set used as rvalue #=EXRESULT FAIL @{FOO}=@{BAR} /bin/foo { /home/@{FOO} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_file_evaluation_8.sd0000644000175000017500000000021313502024172023755 0ustar jjjj#=DESCRIPTION some simple expansions within file rules #=EXRESULT FAIL @{FOO} = /foo /bar /baz /biff /usr/bin/foo { @{FOO}+/.foo/* r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_bad_7.sd0000644000175000017500000000017213502024172021340 0ustar jjjj#=DESCRIPTION variables need closing } #=EXRESULT FAIL @{FOO = /foo /bar /baz /biff /usr/bin/foo { /@{FOO}/.foo/* r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_01.sd0000644000175000017500000000022313502024172023321 0ustar jjjj#=DESCRIPTION reference variables in rules that also have alternations #=EXRESULT PASS @{FOO}=bar /does/not/exist@{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_bad_2.sd0000644000175000017500000000030013502024172021324 0ustar jjjj#=DESCRIPTION garbage should trigger an error #=EXRESULT FAIL @{LIBVIRT} = lib"virt /does/not/exist { change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_7.sd0000644000175000017500000000032013502024172021542 0ustar jjjj#=DESCRIPTION reference variables in dbus rules, with duplicates #=EXRESULT PASS @{FOO}=bar baz bar @{BAR}=@{FOO} blort /does/not/exist { dbus (bind) bus=session name="com.@{BAR}.@{FOO}", } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_auto_profile_name_01.sd0000644000175000017500000000023213502024172024351 0ustar jjjj#=DESCRIPTION reference auto profile_name variable in rules #=EXRESULT PASS /a/test/profile { /a/test/profile rix, /var/run/@{profile_name} rwk, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_10.sd0000644000175000017500000000026113502024172023323 0ustar jjjj#=DESCRIPTION reference variables in rules that also have alternations #=EXRESULT PASS @{FOO}=bar baz @{BAR}=baz profile /does/not@{BAR} /exist@{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_file_evaluation_9.sd0000644000175000017500000000021413502024172023757 0ustar jjjj#=DESCRIPTION some simple expansions within file rules #=EXRESULT PASS @{FOO} = /foo /bar /baz /biff /usr/bin/foo { @{FOO}/=/.foo/* r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_auto_profile_name_07.sd0000644000175000017500000000065613502024172024371 0ustar jjjj#=DESCRIPTION ensure profile_name expansion after subprofiles works #=EXRESULT PASS profile top_profile /test/profile { /test/profile rix, /first/path/@{profile_name}/tmp rwk, /bin/spork Cx -> spork, profile spork { owner /tmp/* r, /run/@{profile_name}/** rw, } hat spelunkk { owner /tmp/* r, /run/@{profile_name}/** rw, } # Does this expand properly? /second/path/@{profile_name}/tmp rk, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_bad_trailing_comma_2.sd0000644000175000017500000000032013502024172024373 0ustar jjjj#=DESCRIPTION trailing commas should trigger an error #=EXRESULT FAIL @{LIBVIRT} = libvirt libtriv, /does/not/exist { change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_recursion_4.sd0000644000175000017500000000025013502024172022615 0ustar jjjj#=DESCRIPTION recursion with multiple values #=EXRESULT FAIL @{FOO} = foo bar baz @{BAR} = @{FOO} @{FOO} += {BAR,foo} @{BAR} /bin/foo { @{FOO} r, /bin/@{BAR} rw, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_simple_assignment_12.sd0000644000175000017500000000033713502024172024412 0ustar jjjj#=DESCRIPTION Test for continuation onto newline #=EXRESULT PASS # the continuation should mean the next line should all be assigned to # this one. @{FOO} = blah \ @{BAR} = baz @{BAR} = notbaz /bin/true { /@{FOO} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_02.sd0000644000175000017500000000022713502024172023326 0ustar jjjj#=DESCRIPTION reference variables in rules that also have alternations #=EXRESULT PASS @{FOO}=bar baz /does/not/exist@{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_8.sd0000644000175000017500000000053613502024172021554 0ustar jjjj#=DESCRIPTION reference variables in dbus rules, embedded within alternation #=EXRESULT PASS @{TLDS}=com org @{DOMAINS}=gnome freedesktop /does/not/exist { dbus (send, receive) bus=session path={/@{TLDS}/foo,/com/@{DOMAINS}} interface=@{TLDS}.freedesktop peer=(name=@{TLDS}.freedesktop label=/@{TLDS}/freedesktop), } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_16.sd0000644000175000017500000000017113502024172023331 0ustar jjjj#=DESCRIPTION var in sub profile name #=EXRESULT PASS @{FOO}=bar profile /does/not/exist { profile foo@{FOO} { } } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_05.sd0000644000175000017500000000023713502024172023332 0ustar jjjj#=DESCRIPTION reference variables in rules that also have alternations #=EXRESULT PASS @{FOO}=bar profile /does/not /exist{@{FOO},} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_bad_1.sd0000644000175000017500000000016013502024172024047 0ustar jjjj#=DESCRIPTION bare profile names must start with / #=EXRESULT FAIL @{FOO}=bar @{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_file_evaluation_11.sd0000644000175000017500000000021513502024172024031 0ustar jjjj#=DESCRIPTION some simple expansions within file rules #=EXRESULT PASS @{FOO} = /foo /bar /baz /biff /usr/bin/foo { "@{FOO}=/.foo/*" r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_bad_01.sd0000644000175000017500000000030213502024172022422 0ustar jjjj# #=DESCRIPTION missing reference variable in dbus bus modifier #=EXRESULT FAIL # /does/not/exist { dbus (send) bus=@{MISSING_VAR} path="/com/canonical/hud/applications/BAR", } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_simple_assignment_4.sd0000644000175000017500000000013313502024172024325 0ustar jjjj#=DESCRIPTION four value set variable assignment #=EXRESULT PASS @{FOO}=foo bar baz blort apparmor-2.13.3/parser/tst/simple_tests/vars/vars_file_evaluation_5.sd0000644000175000017500000000017713502024172023763 0ustar jjjj#=DESCRIPTION some simple expansions within file rules #=EXRESULT PASS @{FOO} = foo bar baz biff /usr/bin/foo { @{FOO} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_alternation_2.sd0000644000175000017500000000027413502024172023130 0ustar jjjj#=DESCRIPTION reference variables in rules that also have alternations #=EXRESULT PASS @{FOO}=bar baz @{BAR}=@{FOO} blort /does/not/exist { /does/not/@{BAR}/blah/{exist,notexist} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_auto_profile_name_06.sd0000644000175000017500000000055213502024172024363 0ustar jjjj#=DESCRIPTION reference auto profile_name variable in rules w/Cx profiles #=EXRESULT PASS profile top_profile /test/profile { /test/profile rix, /run/@{profile_name}/tmp rwk, /bin/spork Cx -> spork, profile spork { owner /tmp/* r, /run/@{profile_name}/** rw, } profile spelunkk { owner /tmp/* r, /run/@{profile_name}/** rw, } } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_20.sd0000644000175000017500000000017113502024172023324 0ustar jjjj#=DESCRIPTION var in sub profile name #=EXRESULT PASS @{FOO}=bar profile /does/not/exist { profile foo@{FOO} { } } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_recursion_1.sd0000644000175000017500000000015013502024172022611 0ustar jjjj#=DESCRIPTION recursive assignment of set #=EXRESULT FAIL @{FOO}=@{FOO} /bin/foo { /home/@{FOO} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_bad_04.sd0000644000175000017500000000031613502024172022432 0ustar jjjj# #=DESCRIPTION missing reference variable in dbus interface modifier #=EXRESULT FAIL # /does/not/exist { dbus (send) interface=@{MISSING_VAR} path="/com/canonical/hud/applications/BAR", } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_9.sd0000644000175000017500000000065113502024172021553 0ustar jjjj#=DESCRIPTION reference variables in dbus rules, multiple expansions #=EXRESULT PASS @{BUSES}=session system @{TLDS}=com org @{DOMAINS}=gnome freedesktop @{FOO}=bar baz @{BAR}=@{FOO}/blort @{MEMBERS}=Get Set /does/not/exist { dbus (send, receive) bus=@{BUSES} path=/@{TLDS}/foo member=@{MEMBERS}.bar interface=@{TLDS}.@{DOMAINS} peer=(name=@{TLDS}.@{DOMAINS} label=/@{TLDS}/@{BAR}), } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_file_evaluation_12.sd0000644000175000017500000000021613502024172024033 0ustar jjjj#=DESCRIPTION some simple expansions within file rules #=EXRESULT PASS @{FOO} = /foo /bar /baz /biff /usr/bin/foo { "@{FOO}+=/.foo/*" r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_auto_profile_name_03.sd0000644000175000017500000000026113502024172024355 0ustar jjjj#=DESCRIPTION reference auto profile_name variable in rules #=EXRESULT PASS profile this_is_a_test /a/test/profile { /a/test/profile rix, /run/@{profile_name}/tmp rwk, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_bad_8.sd0000644000175000017500000000017413502024172021343 0ustar jjjj#=DESCRIPTION variables need matching {} #=EXRESULT FAIL @FOO} = /foo /bar /baz /biff /usr/bin/foo { /@{FOO}/.foo/* r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_25.sd0000644000175000017500000000024413502024172023332 0ustar jjjj#=DESCRIPTION reference variables is null #=EXRESULT FAIL #needs post var expansion check that variable contained a value @{FOO}= @{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_file_evaluation_15.sd0000644000175000017500000000031513502024172024036 0ustar jjjj#=DESCRIPTION simple expansions within file rules with numeric variable #=EXRESULT PASS @{FOO1} = /foo /bar /baz /biff @{B1A1R1} = @{FOO1} /usr/bin/foo { /@{FOO1}/.foo/* r, /foo/@{B1A1R1}/.foo/* r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_alternation_3.sd0000644000175000017500000000023313502024172023124 0ustar jjjj#=DESCRIPTION variable w/part of an alternation included #=EXRESULT PASS @{BAR}={bar,baz,blort /does/not/exist { /does/not/@{BAR},exist,notexist} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_simple_assignment_6.sd0000644000175000017500000000025313502024172024332 0ustar jjjj#=DESCRIPTION multiple references to variables within vars #=EXRESULT PASS @{FOO} = blah @{BAR} @{FOO} += @{BAZ} @{BAZ} = @{BAR} @{BAR} = 2006 /bin/foo { /@{FOO} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_simple_assignment_2.sd0000644000175000017500000000012013502024172024317 0ustar jjjj#=DESCRIPTION two-value set variable assignment #=EXRESULT PASS @{FOO}=bar baz apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_bad_07.sd0000644000175000017500000000032013502024172022430 0ustar jjjj# #=DESCRIPTION missing reference variable in dbus peer name modifier #=EXRESULT FAIL # /does/not/exist { dbus (send) path="/com/canonical/hud/applications/BAR" peer=(name=@{MISSING_VAR}), } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_bad_1.sd0000644000175000017500000000031113502024172021325 0ustar jjjj#=DESCRIPTION trailing garbage should trigger an error #=EXRESULT FAIL @{LIBVIRT} = "libvirt /does/not/exist { change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_bad_2.sd0000644000175000017500000000022113502024172024046 0ustar jjjj#=DESCRIPTION special @{profile_name} not defined for profile name declaration #=EXRESULT FAIL profile @{profile_name} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_auto_profile_name_04.sd0000644000175000017500000000045513502024172024363 0ustar jjjj#=DESCRIPTION reference auto profile_name variable in rules w/hats #=EXRESULT PASS /test/profile { /test/profile rix, /run/@{profile_name}/tmp rwk, ^spork { owner /tmp/* r, /spork/@{profile_name}/** rw, } ^spelunkk { owner /tmp/* r, /spelunk/@{profile_name}/** rw, } } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_17.sd0000644000175000017500000000016613502024172023336 0ustar jjjj#=DESCRIPTION var in sub profile name #=EXRESULT PASS @{FOO}=bar profile /does/not/exist { profile @{FOO} { } } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_5.sd0000644000175000017500000000042013502024172021541 0ustar jjjj#=DESCRIPTION reference variables in dbus rules, with peers #=EXRESULT PASS @{FOO}=bar baz @{BAR}=@{FOO} blort /does/not/exist { dbus (send, receive) bus=session path="/foo/bar" member="bar" peer=(name="com.@{FOO}" label="/usr/bin/app.@{FOO}"), } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_bad_05.sd0000644000175000017500000000030513502024172022431 0ustar jjjj# #=DESCRIPTION missing reference variable in dbus bus modifier #=EXRESULT FAIL # /does/not/exist { dbus (send) member=@{MISSING_VAR} path="/com/canonical/hud/applications/BAR", } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_recursion_3.sd0000644000175000017500000000022613502024172022617 0ustar jjjj#=DESCRIPTION recursive set definitions -- three variables #=EXRESULT FAIL @{FOO}=@{BAR} @{BAR}=@{BAZ} @{BAZ}=@{FOO} /bin/foo { /home/@{FOO} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_simple_assignment_9.sd0000644000175000017500000000012013502024172024326 0ustar jjjj#=DESCRIPTION invalid characters in variable names #=EXRESULT FAIL @{1} = blah apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_11.sd0000644000175000017500000000044013502024172021620 0ustar jjjj#=DESCRIPTION reference variables in dbus rules, nested embedded alternations #=EXRESULT PASS @{BUSES}=session system @{TLDS}=com org @{MEMBERS}={Get,Set} /does/not/exist { dbus (send, receive) bus=@{BUSES} path=/@{TLDS}/foo member={@{MEMBERS}.bar,List.baz}, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_reassignment_1.sd0000644000175000017500000000011113502024172023274 0ustar jjjj#=DESCRIPTION reassignment of set #=EXRESULT FAIL @{FOO}=foo @{FOO}=bar apparmor-2.13.3/parser/tst/simple_tests/vars/vars_file_evaluation_2.sd0000644000175000017500000000022113502024172023746 0ustar jjjj#=DESCRIPTION some simple expansions within file rules #=EXRESULT PASS @{FOO} = foo bar baz biff /usr/bin/foo { /home/@{FOO}/.foo/@{FOO} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_03.sd0000644000175000017500000000022113502024172023321 0ustar jjjj#=DESCRIPTION profiles declared with the profile keyword can begin with var #=EXRESULT PASS @{FOO}=bar profile @{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_bad_06.sd0000644000175000017500000000032213502024172022431 0ustar jjjj# #=DESCRIPTION missing reference variable in dbus peer label modifier #=EXRESULT FAIL # /does/not/exist { dbus (send) path="/com/canonical/hud/applications/BAR" peer=(label=@{MISSING_VAR}), } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_simple_assignment_13.sd0000644000175000017500000000031413502024172024406 0ustar jjjj#=DESCRIPTION quoted commas should not trigger an error #=EXRESULT PASS @{LIBVIRT} = "libvirt," /does/not/exist { change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_file_evaluation_4.sd0000644000175000017500000000020013502024172023745 0ustar jjjj#=DESCRIPTION some simple expansions within file rules #=EXRESULT PASS @{FOO} = foo bar baz biff /usr/bin/foo { /@{FOO} r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_dbus_bad_03.sd0000644000175000017500000000030713502024172022431 0ustar jjjj# #=DESCRIPTION missing reference variable in dbus path modifier #=EXRESULT FAIL # /does/not/exist { dbus (send) bus=session path="/com/canonical/hud/applications/@{MISSING_VAR}", } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_bad_5.sd0000644000175000017500000000022013502024172021330 0ustar jjjj#=DESCRIPTION don't accept variables with leading numeric #=EXRESULT FAIL @{4FOO} = /foo /bar /baz /biff /usr/bin/foo { /@{4FOO}/.foo/* r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_file_evaluation_13.sd0000644000175000017500000000021413502024172024032 0ustar jjjj#=DESCRIPTION some simple expansions within file rules #=EXRESULT PASS @{FOO} = /foo /bar /baz /biff /usr/bin/foo { /@{FOO}=/.foo/* r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_simple_assignment_10.sd0000644000175000017500000000012313502024172024401 0ustar jjjj#=DESCRIPTION invalid characters in variable names #=EXRESULT FAIL @{$FOO} = blah apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_06.sd0000644000175000017500000000024013502024172023325 0ustar jjjj#=DESCRIPTION reference variables in rules that also have alternations #=EXRESULT PASS @{FOO}=bar baz profile /does/not /exist@{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_bad_trailing_comma_4.sd0000644000175000017500000000032013502024172024375 0ustar jjjj#=DESCRIPTION trailing commas should trigger an error #=EXRESULT FAIL @{LIBVIRT} = libvirt, libtriv /does/not/exist { change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/vars/boolean/0000755000175000017500000000000013502024172020420 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/vars/boolean/boolean_bad_2.sd0000644000175000017500000000012613502024172023415 0ustar jjjj#=DESCRIPTION test re-assignment of boolean #=EXRESULT FAIL $FOO = true $FOO = false apparmor-2.13.3/parser/tst/simple_tests/vars/boolean/boolean_bad_7.sd0000644000175000017500000000016413502024172023424 0ustar jjjj# taken from cond8.sd #=DESCRIPTION initial part of word matches 'true', with spaces #=EXRESULT FAIL $FOO = truely apparmor-2.13.3/parser/tst/simple_tests/vars/boolean/boolean_good_1.sd0000644000175000017500000000062713502024172023624 0ustar jjjj#=DESCRIPTION Simple boolean assignment parsing test #=EXRESULT PASS $VAR = True ${BOOLEAN} = fALsE $GUH = true $HO_HUM=TRUE $MEEP = true /bin/foo { #include } apparmor-2.13.3/parser/tst/simple_tests/vars/boolean/boolean_bad_6.sd0000644000175000017500000000014213502024172023417 0ustar jjjj# from condcod6.sd #=DESCRIPTION initial part of word matches 'true' #=EXRESULT FAIL $FOO=truely apparmor-2.13.3/parser/tst/simple_tests/vars/boolean/boolean_bad_8.sd0000644000175000017500000000013613502024172023424 0ustar jjjj# taken from cond10.sd #=DESCRIPTION boolean assignment of an integer #=EXRESULT FAIL $FOO=1 apparmor-2.13.3/parser/tst/simple_tests/vars/boolean/boolean_bad_1.sd0000644000175000017500000000012513502024172023413 0ustar jjjj#=DESCRIPTION Assign boolean non true/false value #=EXRESULT FAIL $VAR = beeblebrox apparmor-2.13.3/parser/tst/simple_tests/vars/boolean/boolean_bad_4.sd0000644000175000017500000000012513502024172023416 0ustar jjjj#=DESCRIPTION test re-assignment of boolean #=EXRESULT FAIL $FOO = true $FOO = True apparmor-2.13.3/parser/tst/simple_tests/vars/boolean/boolean_bad_5.sd0000644000175000017500000000015213502024172023417 0ustar jjjj#=DESCRIPTION Boolean assignments inside policy should fail #=EXRESULT FAIL /bin/foo { $BLAH = false } apparmor-2.13.3/parser/tst/simple_tests/vars/boolean/boolean_bad_3.sd0000644000175000017500000000012513502024172023415 0ustar jjjj#=DESCRIPTION test re-assignment of boolean #=EXRESULT FAIL $FOO = true $FOO = true apparmor-2.13.3/parser/tst/simple_tests/vars/vars_simple_assignment_7.sd0000644000175000017500000000034613502024172024336 0ustar jjjj#=DESCRIPTION valid characters in variable names #=EXRESULT PASS @{ABCDEFGHIJKLMNOPQRSTUVWXYZ_} = bah @{a_bcdefghijklmnopqrstuvwxyz} = @{ABCDEFGHIJKLMNOPQRSTUVWXYZ_}/@{ABCDEFGHIJKLMNOPQRSTUVWXYZ_} ${A1_2_3_4_5_6_7_8_9_0} = False apparmor-2.13.3/parser/tst/simple_tests/vars/vars_profile_name_14.sd0000644000175000017500000000036513502024172023334 0ustar jjjj#=DESCRIPTION reference variables in rules that also have alternations #=EXRESULT PASS # This test needs check on @{FOO} attachment having leading / post var expansion @{FOO}=/bar /baz @{BAR}=baz profile @{BAR} @{FOO} { /does/not/exist r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_file_evaluation_1.sd0000644000175000017500000000021413502024172023747 0ustar jjjj#=DESCRIPTION some simple expansions within file rules #=EXRESULT PASS @{FOO} = foo bar baz biff /usr/bin/foo { /home/@{FOO}/.foo/* r, } apparmor-2.13.3/parser/tst/simple_tests/vars/vars_stress_03.sd0000644000175000017500000000147413502024172022217 0ustar jjjj#=DESCRIPTION stress test (32448 items, 5408 unique) #=EXRESULT PASS @{FOO}=a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z @{BAR}=a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z @{BAZ}=a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z # 52^2 * 3 --> many duplicates --> 52^2 @{FBB}=@{FOO}/@{BAR} @{BAR}/@{BAZ} @{FOO}/@{BAZ} # 52^2 * 3 --> many duplicates --> 52^2 @{BBF}=@{FOO}/FBB/@{BAR} @{BAR}/FBB/@{BAZ} @{FOO}/FBB/@{BAZ} # (52^2) * 2 --> 5408 total entries. # To really up the stress factor, replace the " " with / to give # (52 ^ 2) ^ 2 unique entries, i.e. 7311616 unique entries, 65804544 total @{MEGAFBB}=@{FBB} @{BBF} /bin/foo { /@{MEGAFBB} r, } apparmor-2.13.3/parser/tst/simple_tests/network/0000755000175000017500000000000013502024172017517 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/network/network_ok_1.sd0000644000175000017500000000012213502024172022444 0ustar jjjj# #=DESCRIPTION basic network tests #=EXRESULT PASS # /usr/bin/foo { network, } apparmor-2.13.3/parser/tst/simple_tests/network/netdomain_bad_8.sd0000644000175000017500000000155313502024172023066 0ustar jjjj# #=DESCRIPTION netdomain tcp (accept,connect), udp (send,receive) conglomerate test #=EXRESULT FAIL # /tmp/tcp/tcp_client { tcp_connect to 10.0.0.17/16:50-100 from 0.0.0.0:50-100 via eth1, tcp_connect to 127.0.0.1, tcp_connect from 12.13.14.15/31:21, tcp_accept from 12.13.15.128/25:1024-2048 via eth2, tcp_accept from 10.0.1.1/24:1024-2048 to 192.168.1.1:70 via eth2:1, tcp_accept to 192.168.2.1:70 from 10.0.2.1/24:1024-2048 via eth2:2, tcp_connect to 192.168.3.1:70 from 10.0.3.1/24:1024-2048 via eth2:3, tcp_connect from 10.0.4.1/24:1024-2048 to 192.168.4.1:70 via eth2:4, # syntactic suger cdub asked for: udp_send via eth0, udp_receive via eth1, # attempt an ip style netmask tcp_connect from 10.0.4.1/255.0.255.0:1024-2048 to 192.168.4.1:70 via eth2:4, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/network/tcp_bad_interface.sd0000644000175000017500000000042713502024172023466 0ustar jjjj# #=DESCRIPTION netdomain bad via interface parsing #=EXRESULT FAIL # /tmp/tcp/tcp_client { tcp_connect to 10.0.0.17/16:50-100 from 127.0.0.1 via {}^/ eth1, tcp_connect to 127.0.0.1, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/network/network_bad_3.sd0000644000175000017500000000013313502024172022565 0ustar jjjj# #=DESCRIPTION basic network tests #=EXRESULT FAIL # /usr/bin/foo { network inet foo, } apparmor-2.13.3/parser/tst/simple_tests/network/tcp_client_error6.sd0000644000175000017500000000043213502024172023471 0ustar jjjj# #=DESCRIPTION netdomain tcp connect w/bad CIDR netmask #=EXRESULT FAIL # /tmp/tcp/tcp_client { tcp_connect from 10.0.0.17/16:50-100 to 127.0.0.1 via eth1, tcp_connect to 127.0.0.1/64, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/network/network_ok_2.sd0000644000175000017500000000072613502024172022457 0ustar jjjj# #=DESCRIPTION basic network tests #=EXRESULT PASS # /usr/bin/foo { network unspec, network inet, network ax25, network ipx, network appletalk, network netrom, network bridge, network atmpvc, network x25, network inet6, network rose, network netbeui, network security, network key, network packet, network ash, network econet, network atmsvc, network sna, network irda, network pppox, network wanpipe, network bluetooth, } apparmor-2.13.3/parser/tst/simple_tests/network/netdomain_bad_5.sd0000644000175000017500000000040613502024172023057 0ustar jjjj# #=DESCRIPTION netdomain tcp connect simple parse test (to,via) #=EXRESULT FAIL # /tmp/tcp/tcp_client { tcp_connect to 127.0.0.1, tcp_connect to 10.0.0.17 via eth1, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/network/network_bad_2.sd0000644000175000017500000000012613502024172022566 0ustar jjjj# #=DESCRIPTION basic network tests #=EXRESULT FAIL # /usr/bin/foo { network foo, } apparmor-2.13.3/parser/tst/simple_tests/network/network_bad_1.sd0000644000175000017500000000013713502024172022567 0ustar jjjj# #=DESCRIPTION basic network tests #=EXRESULT FAIL # /usr/bin/foo { network inet raw tcp, } apparmor-2.13.3/parser/tst/simple_tests/network/tcp_client_error2.sd0000644000175000017500000000043613502024172023471 0ustar jjjj# #=DESCRIPTION netdomain tcp connect w/multiple from statments #=EXRESULT FAIL /tmp/tcp/tcp_client { tcp_connect from 10.0.0.17/16:50-100 from 127.0.0.1 via eth1, tcp_connect to 127.0.0.1, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/network/netdomain_bad_2.sd0000644000175000017500000000043013502024172023051 0ustar jjjj# #=DESCRIPTION netdomain tcp accept from ip/cidr netmask/port range via #=EXRESULT FAIL /tmp/tcp/tcp_server { tcp_accept from 10.0.0.17/16:50-100 via eth1, tcp_accept from 127.0.0.1, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/network/network_ok_4.sd0000644000175000017500000000025113502024172022452 0ustar jjjj # #=DESCRIPTION basic network tests #=EXRESULT PASS # /usr/bin/foo { network stream, network dgram, network raw, network tcp, network udp, network icmp, } apparmor-2.13.3/parser/tst/simple_tests/network/network_ok_3.sd0000644000175000017500000000030713502024172022453 0ustar jjjj # #=DESCRIPTION basic network tests #=EXRESULT PASS # /usr/bin/foo { network inet stream, network inet dgram, network inet raw, network inet tcp, network inet udp, network inet icmp, } apparmor-2.13.3/parser/tst/simple_tests/network/tcp_client_error4.sd0000644000175000017500000000044113502024172023467 0ustar jjjj# #=DESCRIPTION netdomain tcp connect w/bad netmask #=EXRESULT FAIL # /tmp/tcp/tcp_client { tcp_connect from 10.0.0.17/16:50-100 to 127.0.0.1 via eth1, tcp_connect to 127.0.0.1/256.512.1024.1, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/network/netdomain_bad_4.sd0000644000175000017500000000051613502024172023060 0ustar jjjj# #=DESCRIPTION netdomain accept from port 65535 #=EXRESULT FAIL # /tmp/tcp/tcp_client { tcp_accept to 10.0.0.17/16:1024-65535 from 127.0.0.1 via eth1, tcp_accept to 10.0.0.18/16:65535 from 127.0.0.1 via eth1, tcp_accept to 127.0.0.1, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/network/netdomain_bad_6.sd0000644000175000017500000000042513502024172023061 0ustar jjjj# #=DESCRIPTION netdomain tcp connect to ip/cidr netmask/port range via #=EXRESULT FAIL /tmp/tcp/tcp_client { tcp_connect to 10.0.0.17/16:50-100 via eth1, tcp_connect to 127.0.0.1, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/network/netdomain_bad_3.sd0000644000175000017500000000041513502024172023055 0ustar jjjj# #=DESCRIPTION netdomain tcp accept from,to,via #=EXRESULT FAIL /tmp/tcp/tcp_server { tcp_accept from 10.0.0.17/16:50-100 to 127.0.0.1 via eth1, tcp_accept from 127.0.0.1, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/network/netdomain_bad_1.sd0000644000175000017500000000041113502024172023047 0ustar jjjj# #=DESCRIPTION netdomain tcp accept simple parse test (from,via) #=EXRESULT FAIL # /tmp/tcp/tcp_server { tcp_accept from 127.0.0.1, tcp_accept from 10.0.0.17 via eth1, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/network/network_ok_5.sd0000644000175000017500000000012713502024172022455 0ustar jjjj# #=DESCRIPTION basic network tests #=EXRESULT PASS # /usr/bin/foo { network unix, } apparmor-2.13.3/parser/tst/simple_tests/network/tcp_client_error3.sd0000644000175000017500000000042513502024172023470 0ustar jjjj# #=DESCRIPTION netdomain tcp_connect w/bad ip address #=EXRESULT FAIL # /tmp/tcp/tcp_client { tcp_connect from 10.0.0.17/16:50-100 to 127.0.0.1 via eth1, tcp_connect to 256.0.0.1, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/network/netdomain_bad_7.sd0000644000175000017500000000041613502024172023062 0ustar jjjj# #=DESCRIPTION netdomain tcp connect to,from,via #=EXRESULT FAIL /tmp/tcp/tcp_client { tcp_connect to 10.0.0.17/16:50-100 from 127.0.0.1 via eth1, tcp_connect to 127.0.0.1, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/network/bad_network_outside_1.sd0000644000175000017500000000011713502024172024321 0ustar jjjj# #=DESCRIPTION network rule outside of a profile #=EXRESULT FAIL # network, apparmor-2.13.3/parser/tst/simple_tests/network/netdomain_bad_9.sd0000644000175000017500000000052013502024172023060 0ustar jjjj# #=DESCRIPTION netdomain connect to port 65535 #=EXRESULT FAIL # /tmp/tcp/tcp_client { tcp_connect to 10.0.0.17/16:1024-65535 from 127.0.0.1 via eth1, tcp_connect to 10.0.0.18/16:65535 from 127.0.0.1 via eth1, tcp_connect to 127.0.0.1, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/network/tcp_client_error7.sd0000644000175000017500000000043513502024172023475 0ustar jjjj# #=DESCRIPTION netdomain tcp connect w/portnumber 65536 #=EXRESULT FAIL # /tmp/tcp/tcp_client { tcp_connect from 10.0.0.17/16:50-100 to 127.0.0.1 via eth1, tcp_connect to 127.0.0.1:65536, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/network/network_bad_4.sd0000644000175000017500000000013013502024172022563 0ustar jjjj# #=DESCRIPTION basic network tests #=EXRESULT FAIL # /usr/bin/foo { network local, } apparmor-2.13.3/parser/tst/simple_tests/network/network_ok_6.sd0000644000175000017500000000013213502024172022452 0ustar jjjj# #=DESCRIPTION basic network tests #=EXRESULT PASS # /usr/bin/foo { network netlink, } apparmor-2.13.3/parser/tst/simple_tests/network/tcp_client_error1.sd0000644000175000017500000000043513502024172023467 0ustar jjjj# #=DESCRIPTION netdomain tcp connect w/multiple to destinations #=EXRESULT FAIL # /tmp/tcp/tcp_client { tcp_connect to 10.0.0.17/16:50-100 to 127.0.0.1 via eth1, tcp_connect to 127.0.0.1, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/network/network_ok_7.sd0000644000175000017500000000022513502024172022456 0ustar jjjj# #=DESCRIPTION basic unspec network tests #=EXRESULT PASS # /usr/bin/foo { network unspec stream, network unspec dgram, network unspec raw, } apparmor-2.13.3/parser/tst/simple_tests/network/tcp_client_error5.sd0000644000175000017500000000043413502024172023472 0ustar jjjj# #=DESCRIPTION netdomain tcp connect w/bad portnumber #=EXRESULT FAIL # /tmp/tcp/tcp_client { tcp_connect from 10.0.0.17/16:50-100 to 127.0.0.1 via eth1, tcp_connect to 127.0.0.1:100000, /lib/libc.so.6 r, /lib/ld-linux.so.2 r, /etc/ld.so.cache r, /lib/libc-2.1.3.so r, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/0000755000175000017500000000000013502024172017345 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_conflicting_x_3.sd0000644000175000017500000000012713502024172025124 0ustar jjjj# #=DESCRIPTION px and ux conflict #=EXRESULT FAIL # /usr/bin/foo { /bin/cat pxux, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/x-conflict2.sd0000644000175000017500000000100313502024172022017 0ustar jjjj# #=DESCRIPTION test for reused flag state #=EXRESULT PASS # /usr/bin/parent-profile { /usr/bin/profile1 Cx -> profile1, /usr/bin/profile2 Cx -> profile2, /usr/bin/profile3 Cx -> profile3, /usr/bin/profile4 Cx -> profile4, /usr/bin/profile5 Cx -> profile5, /usr/bin/profile6 Cx -> profile6, profile profile1 { } profile profile2 { } profile profile3 { } profile profile4 { /usr/bin/apt-get Ux, /usr/bin/dpkg Ux, } profile profile5 { } profile profile6 { } } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_36.sd0000644000175000017500000000045213502024172025065 0ustar jjjj# #=DESCRIPTION test pix - in forward perms P and p are the same and the # unsafe keyword is required. So these should conflict #=EXRESULT FAIL # /usr/bin/foo { /bin/cat pix, /bin/foo Pix, /bin/bar pIx, /bin/a PIx, unsafe pix /bin/cat, pix /bin/foo, pIx /bin/bar, PIx /bin/a, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_conflicting_x_15.sd0000644000175000017500000000012713502024172025207 0ustar jjjj# #=DESCRIPTION Ux and ix conflict #=EXRESULT FAIL # /usr/bin/foo { /bin/cat Uxix, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_30.sd0000644000175000017500000000016213502024172025055 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { rUIx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_15.sd0000644000175000017500000000016213502024172023651 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rppx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_5.sd0000644000175000017500000000015413502024172025000 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { rU /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_20.sd0000644000175000017500000000016213502024172023645 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls riPx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_31.sd0000644000175000017500000000016213502024172023647 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls riux, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_22.sd0000644000175000017500000000016213502024172023647 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rIPx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_32.sd0000644000175000017500000000016213502024172023650 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls riUx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_conflicting_x_10.sd0000644000175000017500000000022413502024172025200 0ustar jjjj# #=DESCRIPTION ux and Ux conflict, different identical rules #=EXRESULT FAIL # /usr/bin/foo { /bin/cat Ux, /lib/lib*.so* rix, /bin/cat ux, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_17.sd0000644000175000017500000000016213502024172023653 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rPpx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_no_bare_x.sd0000644000175000017500000000014613502024172024011 0ustar jjjj# #=DESCRIPTION Require px, ix, or ux, not bare x. #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_ok_x_mods_1.sd0000644000175000017500000000403613502024172023453 0ustar jjjj# #=DESCRIPTION test valid overlapping x mods #=EXRESULT PASS # /usr/bin/foo { /1/1exact px, /1/1* ix, /1/2exact px, /1/2* ux, /1/3exact px, /1/3* Px, /1/4exact px, /1/4* Ux, /1/5exact px, /1/5* pix, /2/1exact ix, /2/1* px, /2/2exact ix, /2/2* ux, /2/3exact ix, /2/3* Px, /2/4exact ix, /2/4* Ux, /2/5exact ix, /2/5* pix, /3/1exact ux, /3/1* ix, /3/2exact ux, /3/2* px, /3/3exact ux, /3/3* Px, /3/4exact ux, /3/4* Ux, /3/5exact ux, /3/5* pix, /4/1exact pix, /4/1* ix, /4/2exact pix, /4/2* ux, /4/3exact pix, /4/3* px, /4/4exact pix, /4/4* Ux, /4/5exact pix, /4/5* Px, /5/1exact px, /5/1** ix, /5/2exact px, /5/2** ux, /5/3exact px, /5/3** Px, /5/4exact px, /5/4** Ux, /5/5exact px, /5/5** pix, /6/1exact ix, /6/1** px, /6/2exact ix, /6/2** ux, /6/3exact ix, /6/3** Px, /6/4exact ix, /6/4** Ux, /6/5exact ix, /6/5** pix, /7/1exact ux, /7/1** ix, /7/2exact ux, /7/2** px, /7/3exact ux, /7/3** Px, /7/4exact ux, /7/4** Ux, /7/5exact ux, /7/5** pix, /8/1exact pix, /8/1** ix, /8/2exact pix, /8/2** ux, /8/3exact pix, /8/3** px, /8/4exact pix, /8/4** Ux, /8/5exact pix, /8/5** Px, /9/1exact px, /9/1exac? ix, /9/2exact px, /9/2exac? ux, /9/3exact px, /9/3exac? Px, /9/4exact px, /9/4exac? Ux, /9/5exact px, /9/5exac? pix, /a/1exact ix, /a/1exac? px, /a/2exact ix, /a/2exac? ux, /a/3exact ix, /a/3exac? Px, /a/4exact ix, /a/4exac? Ux, /a/5exact ix, /a/5exac? pix, /b/1exact ux, /b/1exac? ix, /b/2exact ux, /b/2exac? px, /b/3exact ux, /b/3exac? Px, /b/4exact ux, /b/4exac? Ux, /b/5exact ux, /b/5exac? pix, /c/1exact pix, /c/1exac? ix, /c/2exact pix, /c/2exac? ux, /c/3exact pix, /c/3exac? px, /c/4exact pix, /c/4exac? Ux, /c/5exact pix, /c/5exac? Px, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_conflicting_x_2.sd0000644000175000017500000000022413502024172025121 0ustar jjjj# #=DESCRIPTION px and ix conflict, different identical rules #=EXRESULT FAIL # /usr/bin/foo { /bin/cat px, /lib/lib*.so* rix, /bin/cat ix, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_16.sd0000644000175000017500000000016213502024172025061 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { rpPx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_32.sd0000644000175000017500000000016213502024172025057 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { riUx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_4.sd0000644000175000017500000000015413502024172024777 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { ru /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_15.sd0000644000175000017500000000016213502024172025060 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { rppx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_37.sd0000644000175000017500000000047013502024172025066 0ustar jjjj# #=DESCRIPTION test pix - in forward perms P and p are the same and the # unsafe keyword is required. So these should conflict #=EXRESULT FAIL # /usr/bin/foo { /bin/cat pix, /bin/foo Pix, /bin/bar pIx, /bin/a PIx, unsafe pix /bin/cat, Pix /bin/foo, unsafe pIx /bin/bar, unsafe PIx /bin/a, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_34.sd0000644000175000017500000000016213502024172022301 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rIUx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_26.sd0000644000175000017500000000016213502024172023653 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rUPx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_ok_cx_1.sd0000644000175000017500000000034313502024172022571 0ustar jjjj# #=DESCRIPTION test cx #=EXRESULT PASS # /usr/bin/foo { /bin/cat cx, /bin/foo Cx, unsafe cx /bin/bar, cx /bin/a, profile /bin/cat { /bin/cat mr, } profile /bin/a { /bin/a mr, /tmp/slurp* rw, } } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_conflicting_x_9.sd0000644000175000017500000000012713502024172025132 0ustar jjjj# #=DESCRIPTION ux and Ux conflict #=EXRESULT FAIL # /usr/bin/foo { /bin/cat Uxux, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_23.sd0000644000175000017500000000016213502024172023650 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rupx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_24.sd0000644000175000017500000000016213502024172023651 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls ruPx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_28.sd0000644000175000017500000000016213502024172023655 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls ruIx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_6.sd0000644000175000017500000000015513502024172023573 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { /bin/ls prx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_2.sd0000644000175000017500000000015413502024172023566 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rP, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_30.sd0000644000175000017500000000016213502024172023646 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rUIx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_7.sd0000644000175000017500000000015513502024172023574 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { /bin/ls irx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_10.sd0000644000175000017500000000015513502024172023646 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { /bin/ls Urx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_24.sd0000644000175000017500000000016213502024172025060 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { ruPx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_2.sd0000644000175000017500000000015413502024172024775 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { rP /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_9.sd0000644000175000017500000000015513502024172023576 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { /bin/ls urx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_33.sd0000644000175000017500000000016213502024172025060 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { rIux /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_28.sd0000644000175000017500000000016213502024172025064 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { ruIx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_18.sd0000644000175000017500000000016213502024172025063 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { rPPx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_35.sd0000644000175000017500000000046113502024172025064 0ustar jjjj# #=DESCRIPTION test pix - in forward perms P and p are the same and the # unsafe keyword is required. So these should conflict #=EXRESULT FAIL # /usr/bin/foo { /bin/cat pix, /bin/foo Pix, /bin/bar pIx, /bin/a PIx, unsafe pix /bin/cat, unsafe Pix /bin/foo, pIx /bin/bar, PIx /bin/a, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_conflicting_x_12.sd0000644000175000017500000000022413502024172025202 0ustar jjjj# #=DESCRIPTION ix and Px conflict, different identical rules #=EXRESULT FAIL # /usr/bin/foo { /bin/cat ix, /lib/lib*.so* rix, /bin/cat Px, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_9.sd0000644000175000017500000000015513502024172025005 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { urx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_conflicting_x_7.sd0000644000175000017500000000012713502024172025130 0ustar jjjj# #=DESCRIPTION px and Px conflict #=EXRESULT FAIL # /usr/bin/foo { /bin/cat pxPx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_20.sd0000644000175000017500000000016213502024172025054 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { riPx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_19.sd0000644000175000017500000000016213502024172025064 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { ripx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_18.sd0000644000175000017500000000016213502024172023654 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rPPx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_conflicting_x_5.sd0000644000175000017500000000012713502024172025126 0ustar jjjj# #=DESCRIPTION ux and ix conflict #=EXRESULT FAIL # /usr/bin/foo { /bin/cat uxix, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_19.sd0000644000175000017500000000016213502024172023655 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls ripx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_27.sd0000644000175000017500000000016213502024172023654 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls ruix, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_conflicting_x_11.sd0000644000175000017500000000022413502024172025201 0ustar jjjj# #=DESCRIPTION ux and Px conflict, different identical rules #=EXRESULT FAIL # /usr/bin/foo { /bin/cat ux, /lib/lib*.so* rix, /bin/cat Px, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_8.sd0000644000175000017500000000015513502024172025004 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { irx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_7.sd0000644000175000017500000000015513502024172025003 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { irx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_22.sd0000644000175000017500000000016213502024172025056 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { rIPx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_conflicting_x_1.sd0000644000175000017500000000012713502024172025122 0ustar jjjj# #=DESCRIPTION px and ix conflict #=EXRESULT FAIL # /usr/bin/foo { /bin/cat pxix, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_16.sd0000644000175000017500000000016213502024172023652 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rpPx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_17.sd0000644000175000017500000000016213502024172025062 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { rPpx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/minimize-x-conflict.sd0000644000175000017500000000023013502024172023555 0ustar jjjj# #=DESCRIPTION test for conflict resolution in minimization phase of dfa gen #=EXRESULT PASS # /usr/bin/foo { /b px, /* Pixr, /a Cx -> foo, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_1.sd0000644000175000017500000000015413502024172023565 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rp, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_conflicting_x_8.sd0000644000175000017500000000022413502024172025127 0ustar jjjj# #=DESCRIPTION px and Px conflict, different identical rules #=EXRESULT FAIL # /usr/bin/foo { /bin/cat px, /lib/lib*.so* rix, /bin/cat Px, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_33.sd0000644000175000017500000000016213502024172023651 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rIux, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_29.sd0000644000175000017500000000016213502024172025065 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { rUix /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_21.sd0000644000175000017500000000016213502024172023646 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rIpx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_conflicting_x_4.sd0000644000175000017500000000022413502024172025123 0ustar jjjj# #=DESCRIPTION px and ux conflict, different identical rules #=EXRESULT FAIL # /usr/bin/foo { /bin/cat px, /lib/lib*.so* rix, /bin/cat ux, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_5.sd0000644000175000017500000000015413502024172023571 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rU, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_25.sd0000644000175000017500000000016213502024172023652 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rUpx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_conflicting_x_6.sd0000644000175000017500000000022413502024172025125 0ustar jjjj# #=DESCRIPTION ux and ix conflict, different identical rules #=EXRESULT FAIL # /usr/bin/foo { /bin/cat ux, /lib/lib*.so* rix, /bin/cat ix, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/x-conflict.sd0000644000175000017500000000023013502024172021736 0ustar jjjj# #=DESCRIPTION test for conflict resolution in minimization phase of dfa gen #=EXRESULT FAIL # /usr/bin/foo { /b* px, /* Pixr, /a* Cx -> foo, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_4.sd0000644000175000017500000000015413502024172023570 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { /bin/ls ru, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_3.sd0000644000175000017500000000015413502024172024776 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { ri /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_conflicting_x_14.sd0000644000175000017500000000012713502024172025206 0ustar jjjj# #=DESCRIPTION Px and ix conflict #=EXRESULT FAIL # /usr/bin/foo { /bin/cat ixPx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_3.sd0000644000175000017500000000015413502024172023567 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { /bin/ls ri, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_26.sd0000644000175000017500000000016213502024172025062 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { rUPx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_1.sd0000644000175000017500000000015413502024172024774 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { rp /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_ok_pux_1.sd0000644000175000017500000000054013502024172022772 0ustar jjjj# #=DESCRIPTION pux is allowed as a multiple x modifier #=EXRESULT PASS # /usr/bin/foo { /bin/ls rpux, } /usr/bin/foo2 { /bin/ls rPux, } /usr/bin/foo3 { /bin/ls rpUx, } /usr/bin/foo4 { /bin/ls rPUx, } /usr/bin/foo5 { rpux /bin/ls, } /usr/bin/foo6 { rPux /bin/ls, } /usr/bin/foo7 { rpUx /bin/ls, } /usr/bin/foo8 { rPUx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_ok_pix_1.sd0000644000175000017500000000031113502024172022752 0ustar jjjj# #=DESCRIPTION test pix #=EXRESULT PASS # /usr/bin/foo { /bin/cat pix, /bin/foo Pix, /bin/bar pIx, /bin/a PIx, unsafe pix /bin/cat, Pix /bin/foo, unsafe pix /bin/bar, Pix /bin/a, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_6.sd0000644000175000017500000000015513502024172025002 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { prx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_25.sd0000644000175000017500000000016213502024172025061 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { rUpx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_21.sd0000644000175000017500000000016213502024172025055 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { rIpx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_8.sd0000644000175000017500000000015513502024172023575 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { /bin/ls irx, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_conflicting_x_13.sd0000644000175000017500000000022413502024172025203 0ustar jjjj# #=DESCRIPTION ix and Ux conflict, different identical rules #=EXRESULT FAIL # /usr/bin/foo { /bin/cat ix, /lib/lib*.so* rix, /bin/cat Ux, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_27.sd0000644000175000017500000000016213502024172025063 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { ruix /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_31.sd0000644000175000017500000000016213502024172025056 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { riux /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_10.sd0000644000175000017500000000015513502024172025055 0ustar jjjj# #=DESCRIPTION x modifiers can not appear by themselves #=EXRESULT FAIL # /usr/bin/foo { Urx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_29.sd0000644000175000017500000000016213502024172023656 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { /bin/ls rUix, } apparmor-2.13.3/parser/tst/simple_tests/xtrans/simple_bad_x_mods_first_23.sd0000644000175000017500000000016213502024172025057 0ustar jjjj# #=DESCRIPTION only pix is allowed as a multiple x modifier #=EXRESULT FAIL # /usr/bin/foo { rupx /bin/ls, } apparmor-2.13.3/parser/tst/simple_tests/conditional/0000755000175000017500000000000013502024172020331 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/conditional/ok_4.sd0000644000175000017500000000047713502024172021525 0ustar jjjj#=DESCRIPTION basic conditional statements w/capabilities #=EXRESULT PASS $FOO=true $BAR = False /bin/true { /bin/false rix, capability net_raw, if ${FOO} { capability ipc_lock, } /bin/true rix, if ${BAR} { capability sys_admin, /etc/shadow rw, } /bin/sh rix, capability dac_override, } apparmor-2.13.3/parser/tst/simple_tests/conditional/ok_5.sd0000644000175000017500000000066113502024172021521 0ustar jjjj#=DESCRIPTION basic conditional statements w/hats #=EXRESULT PASS $FOO=true $BAR = False /bin/true { /bin/false rix, capability net_raw, if ${FOO} { capability ipc_lock, ^hat1 { /usr/bin/sendmail rix, } } /bin/true rix, if ${BAR} { capability sys_admin, /etc/shadow rw, ^hat2 { /usr/bin/passwd rix, } } /bin/sh rix, capability dac_override, ^hat3 { /tmp/** rw, } } apparmor-2.13.3/parser/tst/simple_tests/conditional/bad_else_2.sd0000644000175000017500000000044013502024172022636 0ustar jjjj# taken from cond59.sd #=DESCRIPTION improper nesting of hat and conditional #=EXRESULT FAIL $FOO=true #indentation screwy to try to show crossing levels /bin/true { /bin/true rix, if $FOO { ^HATNAME } #endif { /bin/false rix, if $FOO { } #endhat } #endif } apparmor-2.13.3/parser/tst/simple_tests/conditional/else_if_2.sd0000644000175000017500000000045413502024172022513 0ustar jjjj#=DESCRIPTION conditional else #=EXRESULT PASS $FOO=true $FALSE = false /bin/true { ^TRUE { if $FOO { /bin/true rix, } else if $FALSE { /bin/false rix, } } ^FALSE { if not $FOO { /bin/false rix, } else if not ${FALSE} { /bin/true rix, } } } apparmor-2.13.3/parser/tst/simple_tests/conditional/bad_1.sd0000644000175000017500000000023113502024172021623 0ustar jjjj# taken from cond31.sd #=DESCRIPTION boolean assigned inside profile scope #=EXRESULT FAIL /bin/true { $BAR=true if $BAR { /bin/true rix, } } apparmor-2.13.3/parser/tst/simple_tests/conditional/defined_1.sd0000644000175000017500000000030713502024172022477 0ustar jjjj#=DESCRIPTION Conditional tests with 'defined' keyword #=EXRESULT PASS @FOO = "" /bin/true { if defined @FOO { /bin/true rix, } if defined @BAR { /bin/false rix, } /dev/null r, } apparmor-2.13.3/parser/tst/simple_tests/conditional/else_if_1.sd0000644000175000017500000000052013502024172022504 0ustar jjjj#=DESCRIPTION conditional else #=EXRESULT PASS $FOO=true $FALSE = false /bin/true { ^TRUE { if $FOO { /bin/true rix, } else { if $FALSE { /bin/false rix, } } } ^FALSE { if not $FOO { /bin/true rix, } else { if not ${FALSE} { /bin/false rix, } } } } apparmor-2.13.3/parser/tst/simple_tests/conditional/stress_1.sd0000644000175000017500000005455213502024172022437 0ustar jjjj#=DESCRIPTION simple stress test nested ifs #=EXRESULT PASS $a1 = true $a2 = true $a3 = true $a4 = true $a5 = true $a6 = true $a7 = true $a8 = true $a9 = true $a10 = true $a11 = true $a12 = true $a13 = true $a14 = true $a15 = true $a16 = true $a17 = true $a18 = true $a19 = true $a20 = true $a21 = true $a22 = true $a23 = true $a24 = true $a25 = true $a26 = true $a27 = true $a28 = true $a29 = true $a30 = true $a31 = true $a32 = true $a33 = true $a34 = true $a35 = true $a36 = true $a37 = true $a38 = true $a39 = true $a40 = true $a41 = true $a42 = true $a43 = true $a44 = true $a45 = true $a46 = true $a47 = true $a48 = true $a49 = true $a50 = true $a51 = true $a52 = true $a53 = true $a54 = true $a55 = true $a56 = true $a57 = true $a58 = true $a59 = true $a60 = true $a61 = true $a62 = true $a63 = true $a64 = true $a65 = true $a66 = true $a67 = true $a68 = true $a69 = true $a70 = true $a71 = true $a72 = true $a73 = true $a74 = true $a75 = true $a76 = true $a77 = true $a78 = true $a79 = true $a80 = true $a81 = true $a82 = true $a83 = true $a84 = true $a85 = true $a86 = true $a87 = true $a88 = true $a89 = true $a90 = true $a91 = true $a92 = true $a93 = true $a94 = true $a95 = true $a96 = true $a97 = true $a98 = true $a99 = true $a100 = true /bin/true { /bin/true r, if $a1 { if $a2 { if $a3 { if $a4 { if $a5 { if $a6 { if $a7 { if $a8 { if $a9 { if $a10 { if $a11 { if $a12 { if $a13 { if $a14 { if $a15 { if $a16 { if $a17 { if $a18 { if $a19 { if $a20 { if $a21 { if $a22 { if $a23 { if $a24 { if $a25 { if $a26 { if $a27 { if $a28 { if $a29 { if $a30 { if $a31 { if $a32 { if $a33 { if $a34 { if $a35 { if $a36 { if $a37 { if $a38 { if $a39 { if $a40 { if $a41 { if $a42 { if $a43 { if $a44 { if $a45 { if $a46 { if $a47 { if $a48 { if $a49 { if $a50 { if $a51 { if $a52 { if $a53 { if $a54 { if $a55 { if $a56 { if $a57 { if $a58 { if $a59 { if $a60 { if $a61 { if $a62 { if $a63 { if $a64 { if $a65 { if $a66 { if $a67 { if $a68 { if $a69 { if $a70 { if $a71 { if $a72 { if $a73 { if $a74 { if $a75 { if $a76 { if $a77 { if $a78 { if $a79 { if $a80 { if $a81 { if $a82 { if $a83 { if $a84 { if $a85 { if $a86 { if $a87 { if $a88 { if $a89 { if $a90 { if $a91 { if $a92 { if $a93 { if $a94 { if $a95 { if $a96 { if $a97 { if $a98 { if $a99 { if $a100 { /bin/false ux, } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } apparmor-2.13.3/parser/tst/simple_tests/conditional/else_if_5.sd0000644000175000017500000000137513502024172022521 0ustar jjjj#=DESCRIPTION conditional else #=EXRESULT PASS $FOO=true $BAR = false $FALSE = false /bin/true { ^TRUE { if $FOO { /bin/true rix, } else if $FALSE { /bin/false rix, } else if $BAR { /dev/null r, } else if not $FALSE { /dev/null w, } else if defined @B1 { /tmp/1 rw, } else if defined @B2 { /tmp/2 rw, } else if defined @B3 { /tmp/3 rw, } else { /tmp/4 rw, } } ^FALSE { if not $FOO { /bin/false rix, } else if ${FALSE} { /bin/true rix, } else if $BAR { /dev/null r, } else if defined @B1 { /tmp/1 rw, } else if defined @B2 { /tmp/2 rw, } else if defined @B3 { /tmp/3 rw, } else { /tmp/4 rw, } } } apparmor-2.13.3/parser/tst/simple_tests/conditional/ok_3.sd0000644000175000017500000000035413502024172021516 0ustar jjjj#=DESCRIPTION basic conditional statements w/file rules #=EXRESULT PASS $FOO=true $BAR = False /bin/true { /bin/false rix, if ${FOO} { /bin/true rix, } /bin/true rix, if ${BAR} { /etc/shadow rw, } /bin/sh rix, } apparmor-2.13.3/parser/tst/simple_tests/conditional/bad_dup_hats_2.sd0000644000175000017500000000036513502024172023523 0ustar jjjj#=DESCRIPTION duplicated hats inside a conditional #=EXRESULT FAIL ${FOO} = true ${BAR} = true /bin/true { if ${BAR} { ^dupehat { /bin/false rix, } } if ${FOO} { ^dupehat { capability dac_override, } } } apparmor-2.13.3/parser/tst/simple_tests/conditional/else_if_4.sd0000644000175000017500000000044313502024172022513 0ustar jjjj#=DESCRIPTION conditional else in invlaid locations #=EXRESULT FAIL $BAR = false $FOO=true $FALSE = false /bin/true { ^TRUE { if $FOO { /bin/true rix, } else if $FALSE { /bin/false rix, } else if $BAR { /dev/null r, } } else { /dev/null w, } } apparmor-2.13.3/parser/tst/simple_tests/conditional/else_if_8.sd0000644000175000017500000000037213502024172022520 0ustar jjjj#=DESCRIPTION conditional else in invalid locations #=EXRESULT FAIL $BAR = false $FOO=true $FALSE = false /bin/true { if $FOO { /bin/true rix, } else ^FOO { /bin/false rix, } if $FALSE { /dev/null w, } } apparmor-2.13.3/parser/tst/simple_tests/conditional/ok_7.sd0000644000175000017500000000052213502024172021517 0ustar jjjj#=DESCRIPTION basic conditional statements w/hats #=EXRESULT PASS $FOO=true $BAR = False /bin/true { /bin/false rix, capability net_raw, if ${FOO} { ^hat1 { /usr/bin/sendmail rix, } } if not ${FOO} { ^hat1 { /usr/bin/sendmail rux, } } /bin/true rix, /bin/sh rix, capability dac_override, } apparmor-2.13.3/parser/tst/simple_tests/conditional/else_3.sd0000644000175000017500000000044613502024172022037 0ustar jjjj# taken from codn54.sd #=DESCRIPTION conditional within hat scope #=EXRESULT PASS $FOO=true /bin/true { ^TRUE { if $FOO { /bin/true rix, } else { /bin/false rix, } } ^FALSE { if not $FOO { /bin/true rix, } else { /bin/false rix, } } } apparmor-2.13.3/parser/tst/simple_tests/conditional/else_if_7.sd0000644000175000017500000000040113502024172022510 0ustar jjjj#=DESCRIPTION conditional else in invalid locations #=EXRESULT FAIL $BAR = false $FOO=true $FALSE = false /bin/true { if $FOO { /bin/true rix, ^FOO { /bin/false rix, } else if $FALSE { /dev/null w, } } } apparmor-2.13.3/parser/tst/simple_tests/conditional/ok_8.sd0000644000175000017500000000047013502024172021522 0ustar jjjj#=DESCRIPTION basic conditional statements w/hats #=EXRESULT PASS $FOO= false $BAR = False /bin/true { /bin/false rix, capability net_raw, ^hat1 { /usr/bin/sendmail rix, } if ${FOO} { ^hat1 { /usr/bin/sendmail rux, } } /bin/true rix, /bin/sh rix, capability dac_override, } apparmor-2.13.3/parser/tst/simple_tests/conditional/defined_2.sd0000644000175000017500000000047613502024172022507 0ustar jjjj#=DESCRIPTION Conditional tests with 'defined' keyword #=EXRESULT PASS @FOO = "" /bin/true { if not defined @BAR { /bin/true rix, } if not defined @FOO { /bin/false rix, } if not not defined @FOO { /usr/bin/true rix, } if not not defined @BAR { /usr/bin/false rix, } /dev/null r, } apparmor-2.13.3/parser/tst/simple_tests/conditional/ok_6.sd0000644000175000017500000000075113502024172021522 0ustar jjjj#=DESCRIPTION basic conditional statements w/hats #=EXRESULT PASS $FOO=true $BAR = False /bin/true { /bin/false rix, capability net_raw, if ${FOO} { capability ipc_lock, ^hat1 { /usr/bin/sendmail rix, if not $BAR { /usr/sbin/sshd rix, } } } /bin/true rix, if ${BAR} { capability sys_admin, /etc/shadow rw, ^hat2 { /usr/bin/passwd rix, } } /bin/sh rix, capability dac_override, ^hat3 { /tmp/** rw, } } apparmor-2.13.3/parser/tst/simple_tests/conditional/ok_9.sd0000644000175000017500000000104613502024172021523 0ustar jjjj#=DESCRIPTION basic conditional with not statements/weird whitespace #=EXRESULT PASS $FOO=true $BAR = False /bin/true { /bin/false rix, capability net_raw, if not not not not not not not not not not not not not not not not not not not not not not not not not not ${FOO} { /usr/bin/sendmail rux, } /bin/true rix, /bin/sh rix, capability dac_override, } apparmor-2.13.3/parser/tst/simple_tests/conditional/else_if_3.sd0000644000175000017500000000225613502024172022516 0ustar jjjj#=DESCRIPTION conditional else #=EXRESULT PASS $FOO=true $BAR = false $FALSE = false /bin/true { #empty clauses if $FOO { } if $BAR { } if $FOO { } else { } if $BAR { } else { } if $FOO { if $FALSE { } if not $FALSE { } else { } } else { if $BAR { } else { } if $BAR { } else if not $FALSE { } } #unempty clauses if $FOO { /tmp/1 r, } if $BAR { /tmp/2 r, } if $FOO { /tmp/3 r, } else { /tmp/4 r, } if $BAR { /tmp/5 r, } else { /tmp/6 r, } if $FOO { /tmp/7 r, if $FALSE { /tmp/8 r, } if not $FALSE { /tmp/9 r, } else { /tmp/10 r, } } else { /tmp/11 r, if $BAR { /tmp/12 r, } else { /tmp/13 r, } if $BAR { /tmp/14 r, } else if not $FALSE { /tmp/15 r, } } if $BAR { /tmp/16 r, if $FALSE { /tmp/17 r, } if not $FALSE { /tmp/18 r, } else { /tmp/19 r, } } else { /tmp/20 r, if $BAR { /tmp/21 r, } else { /tmp/22 r, } if $BAR { /tmp/23 r, } else if not $FALSE { /tmp/24 r, } } } apparmor-2.13.3/parser/tst/simple_tests/conditional/bad_dup_hats_1.sd0000644000175000017500000000031613502024172023516 0ustar jjjj#=DESCRIPTION duplicated hats inside a conditional #=EXRESULT FAIL ${FOO} = true /bin/true { ^dupehat { /bin/false rix, } if ${FOO} { ^dupehat { capability dac_override, } } } apparmor-2.13.3/parser/tst/simple_tests/conditional/bad_2.sd0000644000175000017500000000017013502024172021626 0ustar jjjj#=DESCRIPTION conditional around only mode #=EXRESULT FAIL $FOO=true /bin/true { /bin/true if $FOO { r, } } apparmor-2.13.3/parser/tst/simple_tests/conditional/else_if_6.sd0000644000175000017500000000031213502024172022510 0ustar jjjj#=DESCRIPTION conditional else in invalid locations #=EXRESULT FAIL $BAR = false $FOO=true $FALSE = false /bin/true { if $FOO { /bin/true rix, } } else if $FALSE { /dev/null w, } apparmor-2.13.3/parser/tst/simple_tests/conditional/ok_2.sd0000644000175000017500000000025413502024172021514 0ustar jjjj# taken from cond48.sd #=DESCRIPTION redundant rule selected by conditional #=EXRESULT PASS $FOO=true /bin/true { if $FOO { /bin/true rix, } /bin/true rix, } apparmor-2.13.3/parser/tst/simple_tests/conditional/bad_3.sd0000644000175000017500000000016513502024172021633 0ustar jjjj#=DESCRIPTION conditional at end of line #=EXRESULT FAIL $FOO=true /bin/true { /bin/true r if $FOO { , } } apparmor-2.13.3/parser/tst/simple_tests/conditional/else_1.sd0000644000175000017500000000037213502024172022033 0ustar jjjj# taken from cond50.sd #=DESCRIPTION simple else clause #=EXRESULT PASS $FOO=true /bin/true { if $FOO { /bin/true rix, } else { /bin/false rix, } } /bin/false { if not $FOO { /bin/true rix, } else { /bin/false rix, } } apparmor-2.13.3/parser/tst/simple_tests/conditional/ok_1.sd0000644000175000017500000000017013502024172021510 0ustar jjjj#=DESCRIPTION conditional within profile #=EXRESULT PASS $FOO=true /bin/true { if $FOO { /bin/true rix, } } apparmor-2.13.3/parser/tst/simple_tests/conditional/else_2.sd0000644000175000017500000000051413502024172022032 0ustar jjjj# taken from cond52.sd #=DESCRIPTION hat defined in if and else clauses #=EXRESULT PASS $FOO=true /bin/true { if $FOO { ^TRUE { /bin/true rix, } } else { ^TRUE { /bin/false rix, } } if not $FOO { ^FALSE { /bin/true rix, } } else { ^FALSE { /bin/false rix, } } } apparmor-2.13.3/parser/tst/simple_tests/conditional/bad_else_1.sd0000644000175000017500000000042413502024172022637 0ustar jjjj# taken from codn55.sd #=DESCRIPTION improper nesting of hat and conditional block #=EXRESULT FAIL $FOO=true # indentation screwy to try to best show 'else' in wrong place /bin/true { if $FOO { ^HAT { /bin/true rix, } else { /bin/bother rix, } } } apparmor-2.13.3/parser/tst/simple_tests/dbus/0000755000175000017500000000000013502024172016763 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/dbus/bad_regex_03.sd0000644000175000017500000000021213502024172021530 0ustar jjjj# #=DESCRIPTION dbus rule with a bad peer regex expansion #=EXRESULT FAIL # profile foo { dbus send bus=session peer=(label=spl{at), } apparmor-2.13.3/parser/tst/simple_tests/dbus/bad_eavesdrop_1.sd0000644000175000017500000000020713502024172022330 0ustar jjjj# #=DESCRIPTION dbus eavesdrop cannot contain non bus modifiers #=EXRESULT FAIL profile dbus_fail { dbus eavesdrop interface=wat, } apparmor-2.13.3/parser/tst/simple_tests/dbus/bad_regex_02.sd0000644000175000017500000000015513502024172021535 0ustar jjjj# #=DESCRIPTION dbus rule with a bad expansion #=EXRESULT FAIL # profile foo { dbus bind name=abcd]efg, } apparmor-2.13.3/parser/tst/simple_tests/dbus/ok_regex_09.sd0000644000175000017500000000025413502024172021427 0ustar jjjj# #=DESCRIPTION dbus rule with a peer regex expansion that are quoted with escaped quote #=EXRESULT PASS # profile foo { dbus send bus=session peer=(label="splat\""), } apparmor-2.13.3/parser/tst/simple_tests/dbus/ok_regex_07.sd0000644000175000017500000000023313502024172021422 0ustar jjjj# #=DESCRIPTION dbus rule with a peer regex expansion that needs escaping #=EXRESULT PASS # profile foo { dbus send bus=session peer=(label=splat\)), } apparmor-2.13.3/parser/tst/simple_tests/dbus/bad_modifier_1.sd0000644000175000017500000000016613502024172022142 0ustar jjjj# #=DESCRIPTION dbus entry with a bad modifier #=EXRESULT FAIL profile foo { dbus send bus=session modifier=foo, } apparmor-2.13.3/parser/tst/simple_tests/dbus/bad_regex_01.sd0000644000175000017500000000021713502024172021533 0ustar jjjj# #=DESCRIPTION dbus rule with a bad bus regex expansion #=EXRESULT FAIL # profile foo { dbus send bus=s{ession,ystem peer=(label=splat), } apparmor-2.13.3/parser/tst/simple_tests/dbus/ok_regex_01.sd0000644000175000017500000000023313502024172021414 0ustar jjjj# #=DESCRIPTION dbus rule with a peer regex expansion that needs escaping #=EXRESULT PASS # profile foo { dbus send bus=session peer=(label=splat\ ), } apparmor-2.13.3/parser/tst/simple_tests/dbus/bad_bind_2.sd0000644000175000017500000000020713502024172021255 0ustar jjjj# #=DESCRIPTION dbus bind with non-bind interface modifier #=EXRESULT FAIL # profile foo { dbus bind bus=session interface=blort, } apparmor-2.13.3/parser/tst/simple_tests/dbus/bad_bind_1.sd0000644000175000017500000000020113502024172021246 0ustar jjjj# #=DESCRIPTION dbus bind with non-bind member modifier #=EXRESULT FAIL # profile foo { dbus bind bus=session member=blort, } apparmor-2.13.3/parser/tst/simple_tests/dbus/ok_regex_06.sd0000644000175000017500000000023313502024172021421 0ustar jjjj# #=DESCRIPTION dbus rule with a peer regex expansion that needs escaping #=EXRESULT PASS # profile foo { dbus send bus=session peer=(label=splat\(), } apparmor-2.13.3/parser/tst/simple_tests/dbus/bad_modifier_3.sd0000644000175000017500000000017213502024172022141 0ustar jjjj# #=DESCRIPTION dbus entry with a bad 'in' keyword #=EXRESULT FAIL profile foo { dbus send bus in (session, system), } apparmor-2.13.3/parser/tst/simple_tests/dbus/bad_modifier_2.sd0000644000175000017500000000017113502024172022137 0ustar jjjj# #=DESCRIPTION dbus entry with a repeated modifier #=EXRESULT FAIL profile foo { dbus send bus=session bus=system, } apparmor-2.13.3/parser/tst/simple_tests/dbus/bad_peer_1.sd0000644000175000017500000000015213502024172021272 0ustar jjjj# #=Description dbus rule with bad 'peer' #=EXRESULT FAIL # profile foo { dbus send peer(label=wat), } apparmor-2.13.3/parser/tst/simple_tests/dbus/ok_eavesdrop_1.sd0000644000175000017500000000017313502024172022215 0ustar jjjj# #=DESCRIPTION simple dbus eavesdrop acceptance test #=EXRESULT PASS profile a_profile { dbus eavesdrop bus=session, } apparmor-2.13.3/parser/tst/simple_tests/dbus/bad_modifier_4.sd0000644000175000017500000000017613502024172022146 0ustar jjjj# #=DESCRIPTION dbus entry with a bad multivalue modifier #=EXRESULT FAIL profile foo { dbus send bus=(session, system), } apparmor-2.13.3/parser/tst/simple_tests/dbus/bad_outside_1.sd0000644000175000017500000000013113502024172022010 0ustar jjjj# #=DESCRIPTION dbus rule outside of a profile #=EXRESULT FAIL dbus name=(SomeService), apparmor-2.13.3/parser/tst/simple_tests/dbus/ok_regex_08.sd0000644000175000017500000000022713502024172021426 0ustar jjjj# #=DESCRIPTION dbus rule with a peer regex expansion that are quoted #=EXRESULT PASS # profile foo { dbus send bus=session peer=(label="splat"), } apparmor-2.13.3/parser/tst/simple_tests/dbus/bad_regex_05.sd0000644000175000017500000000022113502024172021532 0ustar jjjj# #=DESCRIPTION dbus rule with a bad iface regex expansion #=EXRESULT FAIL # profile foo { dbus send interface=Get,Set} peer=(label=splat), } apparmor-2.13.3/parser/tst/simple_tests/dbus/ok_regex_04.sd0000644000175000017500000000023313502024172021417 0ustar jjjj# #=DESCRIPTION dbus rule with a peer regex expansion that needs escaping #=EXRESULT PASS # profile foo { dbus send bus=session peer=(label=splat\!), } apparmor-2.13.3/parser/tst/simple_tests/dbus/ok_bind_1.sd0000644000175000017500000000017413502024172021142 0ustar jjjj# #=DESCRIPTION simple dbus implicit bind acceptance test #=EXRESULT PASS profile a_profile { dbus name=(SomeService), } apparmor-2.13.3/parser/tst/simple_tests/dbus/bad_regex_04.sd0000644000175000017500000000022513502024172021535 0ustar jjjj# #=DESCRIPTION dbus rule with a bad path regex expansion #=EXRESULT FAIL # profile foo { dbus send path=/some/random/{path peer=(label=splat), } apparmor-2.13.3/parser/tst/simple_tests/dbus/ok_regex_03.sd0000644000175000017500000000023313502024172021416 0ustar jjjj# #=DESCRIPTION dbus rule with a peer regex expansion that needs escaping #=EXRESULT PASS # profile foo { dbus send bus=session peer=(label=splat\"), } apparmor-2.13.3/parser/tst/simple_tests/dbus/ok_bind_2.sd0000644000175000017500000000022313502024172021136 0ustar jjjj# #=DESCRIPTION simple dbus implicit bind acceptance test with deny keyword #=EXRESULT PASS profile a_profile { deny dbus name=(SomeService), } apparmor-2.13.3/parser/tst/simple_tests/dbus/ok_regex_05.sd0000644000175000017500000000023313502024172021420 0ustar jjjj# #=DESCRIPTION dbus rule with a peer regex expansion that needs escaping #=EXRESULT PASS # profile foo { dbus send bus=session peer=(label=splat\,), } apparmor-2.13.3/parser/tst/simple_tests/dbus/bad_regex_06.sd0000644000175000017500000000022713502024172021541 0ustar jjjj# #=DESCRIPTION dbus rule with a bad member regex expansion #=EXRESULT FAIL # profile foo { dbus send member=s{{ession,ystem} peer=(label=splat), } apparmor-2.13.3/parser/tst/simple_tests/dbus/ok_regex_02.sd0000644000175000017500000000023313502024172021415 0ustar jjjj# #=DESCRIPTION dbus rule with a peer regex expansion that needs escaping #=EXRESULT PASS # profile foo { dbus send bus=session peer=(label=splat\ ), } apparmor-2.13.3/parser/tst/simple_tests/includes/0000755000175000017500000000000013502024172017634 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/includes/fonts0000644000175000017500000000304613502024172020713 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2002-2006 Novell/SUSE # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ /usr/share/AbiSuite/fonts/** r, /usr/X11R6/lib/X11/fonts/** r, /usr/X11R6/lib/modules/fonts/** r, /usr/X11R6/lib64/X11/fonts/** r, /usr/X11R6/lib64/modules/fonts/** r, /usr/X11R6/include/X11/fonts/** r, /usr/share/fonts/** r, /etc/fonts/** r, /opt/kde3/share/fonts/** r, /usr/lib/openoffice/share/fonts/** r, /usr/lib64/openoffice/share/fonts/** r, /opt/OpenOffice.org/share/fonts/** r, /opt/OpenOffice.org/share/psprint/fontmetric/** r, /opt/OpenOffice.org/user/psprint/fontmetric/** r, /opt/gnome/share/gimp/*/fonts/** r, /opt/gnome/share/fonts/** r, /opt/mozilla/lib/res/fonts/** r, /opt/mozilla/lib64/res/fonts/** r, /var/cache/fonts/** r, /var/cache/fontconfig/** r, /usr/share/a2ps/fonts/** r, /usr/share/xfce/fonts/** r, /usr/share/ghostscript/fonts/** r, /usr/share/texmf/*/fonts/** r, #@{HOME}/.fonts/** r, /usr/local/share/fonts r, /usr/local/share/fonts/** r, apparmor-2.13.3/parser/tst/simple_tests/includes/base0000644000175000017500000000566013502024172020500 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2002-2005 Novell/SUSE # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ # (Note that the ldd profile has inlined this file; if you make # modifications here, please consider including them in the ldd # profile as well.) # The __canary_death_handler function writes a time-stamped log # message to /dev/log for logging by syslogd. So, /dev/log, timezones, # and localisations of date should be available EVERYWHERE, so # StackGuard, FormatGuard, etc., alerts can be properly logged. /dev/log w, /dev/urandom r, /etc/locale/** r, /etc/localtime r, /usr/share/locale/** r, /usr/share/zoneinfo/** r, /usr/lib64/locale/** r, /usr/lib64/gconv/*.so r, /usr/lib64/gconv/gconv-modules* r, /usr/lib/locale/** r, /usr/lib/gconv/*.so r, /usr/lib/gconv/gconv-modules* r, # used by glibc when binding to ephemeral ports /etc/bindresvport.blacklist r, # ld.so.cache and ld are used to load shared libraries; they are best # available everywhere /etc/ld.so.cache r, # 'px' requires a profile to be available for the transition to # function; without a loaded profile, the kernel will fail the exec. /lib/ld-*.so px, /lib64/ld-*.so px, /opt/*-linux-uclibc/lib/ld-uClibc*so* px, # we might as well allow everything to use common libraries /lib/lib*.so* r, /lib/tls/lib*.so* r, /lib/power4/lib*.so* r, /lib/power5/lib*.so* r, /lib/power5+/lib*.so* r, /lib64/power4/lib*.so* r, /lib64/power5/lib*.so* r, /lib64/power5+/lib*.so* r, /usr/lib/*.so* r, /usr/lib/tls/lib*.so* r, /usr/lib/power4/lib*.so* r, /usr/lib/power5/lib*.so* r, /usr/lib/power5+/lib*.so* r, /lib64/lib*.so* r, /lib64/tls/lib*.so* r, /usr/lib64/*.so* r, /usr/lib64/tls/lib*.so* r, # /dev/null is pretty harmless and frequently used /dev/null rw, # as is /dev/zero /dev/zero rw, # Sometimes used to determine kernel/user interfaces to use /proc/sys/kernel/version r, # Depending on which glibc routine uses this file, base may not be the # best place -- but many profiles require it, and it is quite harmless. /proc/sys/kernel/ngroups_max r, # glibc's sysconf(3) routine to determine free memory, etc /proc/meminfo r, /proc/stat r, /proc/cpuinfo r, apparmor-2.13.3/parser/tst/simple_tests/includes/includes with space helper.include0000644000175000017500000000013213502024172026253 0ustar jjjj# #=DESCRIPTION A helper for includes_okay.sd # #include /tmp/** r, apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/0000755000175000017500000000000013502024172021664 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_86.sd0000644000175000017500000000024713502024172023145 0ustar jjjj# #=DESCRIPTION include if exists testing - non-existent include should pass #=EXRESULT PASS # /does/not/exist { include if exists "does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_26.sd0000644000175000017500000000027513502024172023140 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { include "simple_tests/include_tests/includes with space helper.include" } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_62.sd0000644000175000017500000000033413502024172023134 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { include if exists "../tst/simple_tests/include_tests/includes_okay_helper.include" } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ignored_suffix_2/0000755000175000017500000000000013502024172025120 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ignored_suffix_2/good.dpkg-new.include0000644000175000017500000000013313502024172031125 0ustar jjjj#=DESCRIPTION Valid include # # if parsed stand-alone, #=EXRESULT PASS @{FOO} = /foo /bar apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_64.sd0000644000175000017500000000050213502024172023133 0ustar jjjj# #=DESCRIPTION include if existss testing - test some "odd" locations of include if existss #=EXRESULT PASS # /does/not/exist { /does/not/exist mr, include if exists /bin/true Px, include if exists "../tst/simple_tests/include_tests/includes_okay_helper.include" include if exists } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_11.sd0000644000175000017500000000026713502024172023133 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { include "simple_tests/include_tests/includes_okay_helper.include" } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/bad_1.sd0000644000175000017500000000022413502024172023160 0ustar jjjj# #=DESCRIPTION includes testing - non-existent include should fail #=EXRESULT FAIL # /does/not/exist { include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_28.sd0000644000175000017500000000026213502024172023136 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { include <"include_tests/includes with space helper.include"> } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_83.sd0000644000175000017500000000026313502024172023140 0ustar jjjj# #=DESCRIPTION include if exists testing - abs path include does not exist should pass #=EXRESULT PASS # /does/not/exist { include if exists "/does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_87.sd0000644000175000017500000000024713502024172023146 0ustar jjjj# #=DESCRIPTION include if exists testing - non-existent include should pass #=EXRESULT PASS # /does/not/exist { include if exists } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_78.sd0000644000175000017500000000032013502024172023136 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { include if exists <"include_tests/includes with space helper.include"> } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/bad_14.sd0000644000175000017500000000026313502024172023247 0ustar jjjj# #=DESCRIPTION includes testing - non-existent include should fail #=EXRESULT FAIL # /does/not/exist { #include #include "../does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_3.sd0000644000175000017500000000026013502024172023045 0ustar jjjj# #=DESCRIPTION includes testing - basic include of a directory #=EXRESULT PASS # /does/not/exist { include include include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_16.sd0000644000175000017500000000026513502024172023136 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { include simple_tests/include_tests/includes_okay_helper.include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_70.sd0000644000175000017500000000035513502024172023136 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of a directory #=EXRESULT PASS # /does/not/exist { include if exists include if exists simple_tests/includes/ include if exists } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_82.sd0000644000175000017500000000024613502024172023140 0ustar jjjj# #=DESCRIPTION include if exist testing - non-existent include should pass #=EXRESULT PASS # /does/not/exist { include if exists "does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_12.sd0000644000175000017500000000027613502024172023134 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { include "../tst/simple_tests/include_tests/includes_okay_helper.include" } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_69.sd0000644000175000017500000000050013502024172023136 0ustar jjjj# #=DESCRIPTION include if existss testing - test some "odd" locations of include if existss #=EXRESULT PASS # /does/not/exist { /does/not/exist mr, include if exists /bin/true Px, include if exists ../tst/simple_tests/include_tests/includes_okay_helper.include include if exists } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_65.sd0000644000175000017500000000035713502024172023144 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of a directory #=EXRESULT PASS # /does/not/exist { include if exists include if exists "simple_tests/includes/" include if exists } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/bad_4.sd0000644000175000017500000000025613502024172023170 0ustar jjjj# #=DESCRIPTION includes testing - non-existent include should fail #=EXRESULT FAIL # /does/not/exist { include include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_15.sd0000644000175000017500000000027513502024172023136 0ustar jjjj# #=DESCRIPTION includes testing - basic include of a directory #=EXRESULT PASS # /does/not/exist { include include "simple_tests/includes/" include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_66.sd0000644000175000017500000000032313502024172023136 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { include if exists simple_tests/include_tests/includes_okay_helper.include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/bad_12.sd0000644000175000017500000000022513502024172023243 0ustar jjjj# #=DESCRIPTION includes testing - mis-parsing include should fail #=EXRESULT FAIL # /does/not/exist { #include "/does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_31.sd0000644000175000017500000000027413502024172023133 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { include #comment } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_19.sd0000644000175000017500000000041613502024172023137 0ustar jjjj# #=DESCRIPTION includes testing - test some "odd" locations of includes #=EXRESULT PASS # /does/not/exist { /does/not/exist mr, include /bin/true Px, include ../tst/simple_tests/include_tests/includes_okay_helper.include include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_88.sd0000644000175000017500000000030113502024172023136 0ustar jjjj# #=DESCRIPTION include if exists testing - non-existent include should pass #=EXRESULT PASS # /does/not/exist { include if exists include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_76.sd0000644000175000017500000000033313502024172023140 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { include if exists "simple_tests/include_tests/includes with space helper.include" } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ignored_suffix_2.sd0000644000175000017500000000024613502024172025452 0ustar jjjj# #=DESCRIPTION includes testing - verify that only suffixes are ignored #=EXRESULT PASS # include /does/not/exist { @{FOO} r, } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ignored_suffix/0000755000175000017500000000000013502024172024677 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ignored_suffix/bad-include.dpkg-dist0000644000175000017500000000002513502024172030653 0ustar jjjjTHIS WILL NOT PARSE! apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ignored_suffix/bad-include.dpkg-old0000644000175000017500000000002513502024172030466 0ustar jjjjTHIS WILL NOT PARSE! apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ignored_suffix/bad-include.dpkg-new0000644000175000017500000000002513502024172030501 0ustar jjjjTHIS WILL NOT PARSE! apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ignored_suffix/bad-include.dpkg-bak0000644000175000017500000000002513502024172030445 0ustar jjjjTHIS WILL NOT PARSE! apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ignored_suffix/good-include0000644000175000017500000000013313502024172027170 0ustar jjjj#=DESCRIPTION Valid include # # if parsed stand-alone, #=EXRESULT PASS @{FOO} = /foo /bar apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ignored_suffix/bad-include.rpmnew0000644000175000017500000000002513502024172030275 0ustar jjjjTHIS WILL NOT PARSE! apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ignored_suffix/bad-include~0000644000175000017500000000002513502024172027164 0ustar jjjjTHIS WILL NOT PARSE! apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ignored_suffix/bad-include.rpmsave0000644000175000017500000000002513502024172030442 0ustar jjjjTHIS WILL NOT PARSE! apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_14.sd0000644000175000017500000000042013502024172023125 0ustar jjjj# #=DESCRIPTION includes testing - test some "odd" locations of includes #=EXRESULT PASS # /does/not/exist { /does/not/exist mr, include /bin/true Px, include "../tst/simple_tests/include_tests/includes_okay_helper.include" include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ignored_suffix_1.sd0000644000175000017500000000024713502024172025452 0ustar jjjj# #=DESCRIPTION includes testing - verify that ignored suffixes are ignored #=EXRESULT PASS # include /does/not/exist { @{FOO} r, } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_63.sd0000644000175000017500000000032713502024172023137 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { include if exists "./simple_tests/include_tests/includes_okay_helper.include" } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_20.sd0000644000175000017500000000027313502024172023130 0ustar jjjj# #=DESCRIPTION includes testing - basic include of a directory #=EXRESULT PASS # /does/not/exist { include include simple_tests/includes/ include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_18.sd0000644000175000017500000000026713502024172023142 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { include ./simple_tests/include_tests/includes_okay_helper.include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_79.sd0000644000175000017500000000033213502024172023142 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { include if exists <"include_tests/includes with space helper.include"> #comment } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/recursive.sd0000644000175000017500000000021613502024172024222 0ustar jjjj# #=DESCRIPTION includes testing - recursive include should fail #=EXRESULT FAIL # /does/not/exist { include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_77.sd0000644000175000017500000000034513502024172023144 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { include if exists "simple_tests/include_tests/includes with space helper.include" #comment } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/includes_okay_helper.include0000644000175000017500000000020313502024172027414 0ustar jjjj# #=DESCRIPTION A helper for includes_okay.sd # # if parsed standalone, #=EXRESULT FAIL # include /tmp/** r, apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/bad_13.sd0000644000175000017500000000026013502024172023243 0ustar jjjj# #=DESCRIPTION includes testing - non-existent include should fail #=EXRESULT FAIL # /does/not/exist { #include "does-not-exist/does-not-exist" #include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_81.sd0000644000175000017500000000033213502024172023133 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { include if exists #comment } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_67.sd0000644000175000017500000000033213502024172023137 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { include if exists ../tst/simple_tests/include_tests/includes_okay_helper.include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_13.sd0000644000175000017500000000027113502024172023130 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { include "./simple_tests/include_tests/includes_okay_helper.include" } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/bad_11.sd0000644000175000017500000000022513502024172023242 0ustar jjjj# #=DESCRIPTION includes testing - non-existent include should fail #=EXRESULT FAIL # /does/not/exist { #include "does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_80.sd0000644000175000017500000000031613502024172023134 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { include if exists } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_84.sd0000644000175000017500000000030413502024172023135 0ustar jjjj# #=DESCRIPTION include if exists testing - non-existent include should pass #=EXRESULT PASS # /does/not/exist { include include if exists "../does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_61.sd0000644000175000017500000000032513502024172023133 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { include if exists "simple_tests/include_tests/includes_okay_helper.include" } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_30.sd0000644000175000017500000000026013502024172023125 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/bad_2.sd0000644000175000017500000000022113502024172023156 0ustar jjjj# #=DESCRIPTION includes testing - mis-parsing include should fail #=EXRESULT FAIL # /does/not/exist { include does-not-exist/does-not-exist } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_27.sd0000644000175000017500000000030713502024172023135 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { include "simple_tests/include_tests/includes with space helper.include" #comment } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_85.sd0000644000175000017500000000030413502024172023136 0ustar jjjj# #=DESCRIPTION include if exists testing - non-existent include should pass #=EXRESULT PASS # /does/not/exist { include include if exists "../does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_2.sd0000644000175000017500000000037613502024172023054 0ustar jjjj# #=DESCRIPTION includes testing - test some "odd" locations of includes #=EXRESULT PASS # /does/not/exist { /does/not/exist mr, #include /bin/true Px, include #include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/bad_3.sd0000644000175000017500000000025613502024172023167 0ustar jjjj# #=DESCRIPTION includes testing - non-existent include should fail #=EXRESULT FAIL # /does/not/exist { include include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_29.sd0000644000175000017500000000027413502024172023142 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { include <"include_tests/includes with space helper.include"> #comment } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_17.sd0000644000175000017500000000027413502024172023137 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { include ../tst/simple_tests/include_tests/includes_okay_helper.include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_1.sd0000644000175000017500000000034113502024172023043 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { #include #include #include } apparmor-2.13.3/parser/tst/simple_tests/bare_include_tests/ok_68.sd0000644000175000017500000000032513502024172023142 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { include if exists ./simple_tests/include_tests/includes_okay_helper.include } apparmor-2.13.3/parser/tst/simple_tests/mount/0000755000175000017500000000000013502024172017170 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/mount/in_2.sd0000644000175000017500000000015113502024172020344 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount options in (rw, ro) -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_35.sd0000644000175000017500000000046013502024172021322 0ustar jjjj# #=Description basic rules to test the "noiversion" mount option #=EXRESULT PASS /usr/bin/foo { mount options=noiversion /a -> /1, mount options=(noiversion) /b -> /2, mount options=(rw,noiversion) /c -> /3, mount options in (noiversion) /d -> /4, mount options in (ro,noiversion) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_2.sd0000644000175000017500000000026513502024172021237 0ustar jjjj# #=Description basic rules to test the "r" mount option #=EXRESULT PASS /usr/bin/foo { mount options=r /a -> /1, mount options=(r) /b -> /2, mount options in (r) /d -> /4, } apparmor-2.13.3/parser/tst/simple_tests/mount/in_1.sd0000644000175000017500000000014513502024172020346 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount options in (rw) -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_46.sd0000644000175000017500000000041113502024172021320 0ustar jjjj# #=Description basic rules to test the "rslave" mount option #=EXRESULT PASS /usr/bin/foo { mount options=rslave -> /1, mount options=(rslave) -> /2, mount options=(rw,rslave) -> /3, mount options in (rslave) -> /4, mount options in (ro,rslave) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_22.sd0000644000175000017500000000037213502024172021320 0ustar jjjj# #=Description basic rules to test the "B" mount option #=EXRESULT PASS /usr/bin/foo { mount options=B /a -> /1, mount options=(B) /b -> /2, mount options=(rw,B) /c -> /3, mount options in (B) /d -> /4, mount options in (ro,B) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_4.sd0000644000175000017500000000013013502024172020346 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount /{foo,bar}, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_16.sd0000644000175000017500000000023313502024172021434 0ustar jjjj# #=Description basic rule to test the valid "rshared" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(rshared) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_3.sd0000644000175000017500000000020513502024172021347 0ustar jjjj# #=Description basic rule to test the invalid "load" mount option #=EXRESULT FAIL /usr/bin/foo { mount options=(load) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_21.sd0000644000175000017500000000025513502024172021434 0ustar jjjj# #=Description basic rule to test the valid "make-runbindable" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(make-runbindable) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_21.sd0000644000175000017500000000013213502024172020427 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount /bar -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_5.sd0000644000175000017500000000015413502024172020355 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # @{mntpnt}=/foo/bar /usr/bin/foo { mount @{mntpnt}, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_12.sd0000644000175000017500000000041413502024172021314 0ustar jjjj# #=Description basic rules to test the "sync" mount option #=EXRESULT PASS /usr/bin/foo { mount options=sync /a -> /1, mount options=(sync) /b -> /2, mount options=(rw,sync) /c -> /3, mount options in (sync) /d -> /4, mount options in (ro,sync) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_11.sd0000644000175000017500000000015413502024172020432 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount fstype=(procfs, sysfs) -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_55.sd0000644000175000017500000000045513502024172021330 0ustar jjjj# #=Description basic rules to test the "make-rshared" mount option #=EXRESULT PASS /usr/bin/foo { mount options=make-rshared -> /1, mount options=(make-rshared) -> /2, mount options=(rw,make-rshared) -> /3, mount options in (make-rshared) -> /4, mount options in (ro,make-rshared) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_21.sd0000644000175000017500000000041413502024172021314 0ustar jjjj# #=Description basic rules to test the "bind" mount option #=EXRESULT PASS /usr/bin/foo { mount options=bind /a -> /1, mount options=(bind) /b -> /2, mount options=(rw,bind) /c -> /3, mount options in (bind) /d -> /4, mount options in (ro,bind) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_25.sd0000644000175000017500000000041413502024172021320 0ustar jjjj# #=Description basic rules to test the "move" mount option #=EXRESULT PASS /usr/bin/foo { mount options=move /a -> /1, mount options=(move) /b -> /2, mount options=(rw,move) /c -> /3, mount options in (move) /d -> /4, mount options in (ro,move) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_20.sd0000644000175000017500000000024313502024172021430 0ustar jjjj# #=Description basic rule to test the valid "make-shared" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(make-shared) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_10.sd0000644000175000017500000000043013502024172021310 0ustar jjjj# #=Description basic rules to test the "noexec" mount option #=EXRESULT PASS /usr/bin/foo { mount options=noexec /a -> /1, mount options=(noexec) /b -> /2, mount options=(rw,noexec) /c -> /3, mount options in (noexec) /d -> /4, mount options in (ro,noexec) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_19.sd0000644000175000017500000000046013502024172021324 0ustar jjjj# #=Description basic rules to test the "nodiratime" mount option #=EXRESULT PASS /usr/bin/foo { mount options=nodiratime /a -> /1, mount options=(nodiratime) /b -> /2, mount options=(rw,nodiratime) /c -> /3, mount options in (nodiratime) /d -> /4, mount options in (ro,nodiratime) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_5.sd0000644000175000017500000000026513502024172021242 0ustar jjjj# #=Description basic rules to test the "w" mount option #=EXRESULT PASS /usr/bin/foo { mount options=w /a -> /1, mount options=(w) /b -> /2, mount options in (w) /d -> /4, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_24.sd0000644000175000017500000000037213502024172021322 0ustar jjjj# #=Description basic rules to test the "R" mount option #=EXRESULT PASS /usr/bin/foo { mount options=R /a -> /1, mount options=(R) /b -> /2, mount options=(rw,R) /c -> /3, mount options in (R) /d -> /4, mount options in (ro,R) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_4.sd0000644000175000017500000000020313502024172021346 0ustar jjjj# #=Description basic rule to test the invalid "rec" mount option #=EXRESULT FAIL /usr/bin/foo { mount options=(rec) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_23.sd0000644000175000017500000000012313502024172020431 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { umount /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_41.sd0000644000175000017500000000041713502024172021321 0ustar jjjj# #=Description basic rules to test the "private" mount option #=EXRESULT PASS /usr/bin/foo { mount options=private -> /1, mount options=(private) -> /2, mount options=(rw,private) -> /3, mount options in (private) -> /4, mount options in (ro,private) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_10.sd0000644000175000017500000000023313502024172021426 0ustar jjjj# #=Description basic rule to test the valid "private" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(private) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_39.sd0000644000175000017500000000041713502024172021330 0ustar jjjj# #=Description basic rules to test the "remount" mount option #=EXRESULT PASS /usr/bin/foo { mount options=remount -> /1, mount options=(remount) -> /2, mount options=(rw,remount) -> /3, mount options in (remount) -> /4, mount options in (ro,remount) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_11.sd0000644000175000017500000000022713502024172021432 0ustar jjjj# #=Description basic rule to test the valid "slave" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(slave) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_6.sd0000644000175000017500000000022113502024172021350 0ustar jjjj# #=Description basic rule to test the invalid "norelative" mount option #=EXRESULT FAIL /usr/bin/foo { mount options=(norelative) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_11.sd0000644000175000017500000000041413502024172021313 0ustar jjjj# #=Description basic rules to test the "exec" mount option #=EXRESULT PASS /usr/bin/foo { mount options=exec /a -> /1, mount options=(exec) /b -> /2, mount options=(rw,exec) /c -> /3, mount options in (exec) /d -> /4, mount options in (ro,exec) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_47.sd0000644000175000017500000000041713502024172021327 0ustar jjjj# #=Description basic rules to test the "rshared" mount option #=EXRESULT PASS /usr/bin/foo { mount options=rshared -> /1, mount options=(rshared) -> /2, mount options=(rw,rshared) -> /3, mount options in (rshared) -> /4, mount options in (ro,rshared) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_32.sd0000644000175000017500000000044413502024172021321 0ustar jjjj# #=Description basic rules to test the "relatime" mount option #=EXRESULT PASS /usr/bin/foo { mount options=relatime /a -> /1, mount options=(relatime) /b -> /2, mount options=(rw,relatime) /c -> /3, mount options in (relatime) /d -> /4, mount options in (ro,relatime) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_3.sd0000644000175000017500000000012113502024172020345 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount /**, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_40.sd0000644000175000017500000000044113502024172021315 0ustar jjjj# #=Description basic rules to test the "unbindable" mount option #=EXRESULT PASS /usr/bin/foo { mount options=unbindable -> /1, mount options=(unbindable) -> /2, mount options=(rw,unbindable) -> /3, mount options in (unbindable) -> /4, mount options in (ro,unbindable) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_44.sd0000644000175000017500000000044713502024172021327 0ustar jjjj# #=Description basic rules to test the "runbindable" mount option #=EXRESULT PASS /usr/bin/foo { mount options=runbindable -> /1, mount options=(runbindable) -> /2, mount options=(rw,runbindable) -> /3, mount options in (runbindable) -> /4, mount options in (ro,runbindable) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/in_3.sd0000644000175000017500000000015013502024172020344 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount options in (rw ro) -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_28.sd0000644000175000017500000000043013502024172021321 0ustar jjjj# #=Description basic rules to test the "silent" mount option #=EXRESULT PASS /usr/bin/foo { mount options=silent /a -> /1, mount options=(silent) /b -> /2, mount options=(rw,silent) /c -> /3, mount options in (silent) /d -> /4, mount options in (ro,silent) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_16.sd0000644000175000017500000000014613502024172020440 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount options=(rw, ro) -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_10.sd0000644000175000017500000000014513502024172020431 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount fstype=(procfs) -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_51.sd0000644000175000017500000000044713502024172021325 0ustar jjjj# #=Description basic rules to test the "make-shared" mount option #=EXRESULT PASS /usr/bin/foo { mount options=make-shared -> /1, mount options=(make-shared) -> /2, mount options=(rw,make-shared) -> /3, mount options in (make-shared) -> /4, mount options in (ro,make-shared) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_52.sd0000644000175000017500000000050513502024172021321 0ustar jjjj# #=Description basic rules to test the "make-runbindable" mount option #=EXRESULT PASS /usr/bin/foo { mount options=make-runbindable -> /1, mount options=(make-runbindable) -> /2, mount options=(rw,make-runbindable) -> /3, mount options in (make-runbindable) -> /4, mount options in (ro,make-runbindable) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_42.sd0000644000175000017500000000040313502024172021315 0ustar jjjj# #=Description basic rules to test the "slave" mount option #=EXRESULT PASS /usr/bin/foo { mount options=slave -> /1, mount options=(slave) -> /2, mount options=(rw,slave) -> /3, mount options in (slave) -> /4, mount options in (ro,slave) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_12.sd0000644000175000017500000000015313502024172020432 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount fstype={procfs,sysfs} -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_17.sd0000644000175000017500000000043613502024172021325 0ustar jjjj# #=Description basic rules to test the "noatime" mount option #=EXRESULT PASS /usr/bin/foo { mount options=noatime /a -> /1, mount options=(noatime) /b -> /2, mount options=(rw,noatime) /c -> /3, mount options in (noatime) /d -> /4, mount options in (ro,noatime) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_15.sd0000644000175000017500000000023113502024172021431 0ustar jjjj# #=Description basic rule to test the valid "rslave" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(rslave) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_23.sd0000644000175000017500000000042213502024172021315 0ustar jjjj# #=Description basic rules to test the "rbind" mount option #=EXRESULT PASS /usr/bin/foo { mount options=rbind /a -> /1, mount options=(rbind) /b -> /2, mount options=(rw,rbind) /c -> /3, mount options in (rbind) /d -> /4, mount options in (ro,rbind) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_18.sd0000644000175000017500000000024513502024172021441 0ustar jjjj# #=Description basic rule to test the valid "make-private" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(make-private) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_1.sd0000644000175000017500000000020313502024172021343 0ustar jjjj# #=Description basic rule to test the invalid "XXX" mount option #=EXRESULT FAIL /usr/bin/foo { mount options=(XXX) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_18.sd0000644000175000017500000000042213502024172021321 0ustar jjjj# #=Description basic rules to test the "atime" mount option #=EXRESULT PASS /usr/bin/foo { mount options=atime /a -> /1, mount options=(atime) /b -> /2, mount options=(rw,atime) /c -> /3, mount options in (atime) /d -> /4, mount options in (ro,atime) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_54.sd0000644000175000017500000000044713502024172021330 0ustar jjjj# #=Description basic rules to test the "make-rslave" mount option #=EXRESULT PASS /usr/bin/foo { mount options=make-rslave -> /1, mount options=(make-rslave) -> /2, mount options=(rw,make-rslave) -> /3, mount options in (make-rslave) -> /4, mount options in (ro,make-rslave) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_50.sd0000644000175000017500000000044113502024172021316 0ustar jjjj# #=Description basic rules to test the "make-slave" mount option #=EXRESULT PASS /usr/bin/foo { mount options=make-slave -> /1, mount options=(make-slave) -> /2, mount options=(rw,make-slave) -> /3, mount options in (make-slave) -> /4, mount options in (ro,make-slave) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_1.sd0000644000175000017500000000027113502024172021233 0ustar jjjj# #=Description basic rules to test the "ro" mount option #=EXRESULT PASS /usr/bin/foo { mount options=ro /a -> /1, mount options=(ro) /b -> /2, mount options in (ro) /d -> /4, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_3.sd0000644000175000017500000000032513502024172021235 0ustar jjjj# #=Description basic rules to test the "read-only" mount option #=EXRESULT PASS /usr/bin/foo { mount options=read-only /a -> /1, mount options=(read-only) /b -> /2, mount options in (read-only) /d -> /4, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_49.sd0000644000175000017500000000045513502024172021333 0ustar jjjj# #=Description basic rules to test the "make-private" mount option #=EXRESULT PASS /usr/bin/foo { mount options=make-private -> /1, mount options=(make-private) -> /2, mount options=(rw,make-private) -> /3, mount options in (make-private) -> /4, mount options in (ro,make-private) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_33.sd0000644000175000017500000000046013502024172021320 0ustar jjjj# #=Description basic rules to test the "norelatime" mount option #=EXRESULT PASS /usr/bin/foo { mount options=norelatime /a -> /1, mount options=(norelatime) /b -> /2, mount options=(rw,norelatime) /c -> /3, mount options in (norelatime) /d -> /4, mount options in (ro,norelatime) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_9.sd0000644000175000017500000000040613502024172021243 0ustar jjjj# #=Description basic rules to test the "dev" mount option #=EXRESULT PASS /usr/bin/foo { mount options=dev /a -> /1, mount options=(dev) /b -> /2, mount options=(rw,dev) /c -> /3, mount options in (dev) /d -> /4, mount options in (ro,dev) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_15.sd0000644000175000017500000000014213502024172020433 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount options=(rw) -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_22.sd0000644000175000017500000000024713502024172021436 0ustar jjjj# #=Description basic rule to test the valid "make-rprivate" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(make-rprivate) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_27.sd0000644000175000017500000000043613502024172021326 0ustar jjjj# #=Description basic rules to test the "verbose" mount option #=EXRESULT PASS /usr/bin/foo { mount options=verbose /a -> /1, mount options=(verbose) /b -> /2, mount options=(rw,verbose) /c -> /3, mount options in (verbose) /d -> /4, mount options in (ro,verbose) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_17.sd0000644000175000017500000000025313502024172021437 0ustar jjjj# #=Description basic rule to test the valid "make-unbindable" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(make-unbindable) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_16.sd0000644000175000017500000000043613502024172021324 0ustar jjjj# #=Description basic rules to test the "dirsync" mount option #=EXRESULT PASS /usr/bin/foo { mount options=dirsync /a -> /1, mount options=(dirsync) /b -> /2, mount options=(rw,dirsync) /c -> /3, mount options in (dirsync) /d -> /4, mount options in (ro,dirsync) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_19.sd0000644000175000017500000000017213502024172020442 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount options=(rw ro) fstype=(procfs) none -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_5.sd0000644000175000017500000000021513502024172021352 0ustar jjjj# #=Description basic rule to test the invalid "relative" mount option #=EXRESULT FAIL /usr/bin/foo { mount options=(relative) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_8.sd0000644000175000017500000000017313502024172020361 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # @{dev}=/one /two /three /four /usr/bin/foo { mount @{dev} -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_14.sd0000644000175000017500000000041413502024172021316 0ustar jjjj# #=Description basic rules to test the "mand" mount option #=EXRESULT PASS /usr/bin/foo { mount options=mand /a -> /1, mount options=(mand) /b -> /2, mount options=(rw,mand) /c -> /3, mount options in (mand) /d -> /4, mount options in (ro,mand) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/okay_13.sd0000644000175000017500000000015313502024172020765 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount fstype=(procfs sysfs) -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_43.sd0000644000175000017500000000041113502024172021315 0ustar jjjj# #=Description basic rules to test the "shared" mount option #=EXRESULT PASS /usr/bin/foo { mount options=shared -> /1, mount options=(shared) -> /2, mount options=(rw,shared) -> /3, mount options in (shared) -> /4, mount options in (ro,shared) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_15.sd0000644000175000017500000000043013502024172021315 0ustar jjjj# #=Description basic rules to test the "nomand" mount option #=EXRESULT PASS /usr/bin/foo { mount options=nomand /a -> /1, mount options=(nomand) /b -> /2, mount options=(rw,nomand) /c -> /3, mount options in (nomand) /d -> /4, mount options in (ro,nomand) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_8.sd0000644000175000017500000000042213502024172021240 0ustar jjjj# #=Description basic rules to test the "nodev" mount option #=EXRESULT PASS /usr/bin/foo { mount options=nodev /a -> /1, mount options=(nodev) /b -> /2, mount options=(rw,nodev) /c -> /3, mount options in (nodev) /d -> /4, mount options in (ro,nodev) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_48.sd0000644000175000017500000000047713502024172021336 0ustar jjjj# #=Description basic rules to test the "make-unbindable" mount option #=EXRESULT PASS /usr/bin/foo { mount options=make-unbindable -> /1, mount options=(make-unbindable) -> /2, mount options=(rw,make-unbindable) -> /3, mount options in (make-unbindable) -> /4, mount options in (ro,make-unbindable) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_14.sd0000644000175000017500000000016013502024172020432 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount fstype=(procfs sysfs) none -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_36.sd0000644000175000017500000000046613502024172021331 0ustar jjjj# #=Description basic rules to test the "strictatime" mount option #=EXRESULT PASS /usr/bin/foo { mount options=strictatime /a -> /1, mount options=(strictatime) /b -> /2, mount options=(rw,strictatime) /c -> /3, mount options in (strictatime) /d -> /4, mount options in (ro,strictatime) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_20.sd0000644000175000017500000000015113502024172020427 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount options=(bind) /bar -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_9.sd0000644000175000017500000000024113502024172021355 0ustar jjjj# #=Description basic rule to test the valid "unbindable" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(unbindable) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_23.sd0000644000175000017500000000024313502024172021433 0ustar jjjj# #=Description basic rule to test the valid "make-rslave" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(make-rslave) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/okay_6.sd0000644000175000017500000000013613502024172020710 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount /dev/bar -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/in_4.sd0000644000175000017500000000016613502024172020354 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount options in (rw ro) fstype=procfs -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_18.sd0000644000175000017500000000016313502024172020441 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount options=(rw ro) fstype=procfs -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_7.sd0000644000175000017500000000041413502024172021240 0ustar jjjj# #=Description basic rules to test the "suid" mount option #=EXRESULT PASS /usr/bin/foo { mount options=suid /a -> /1, mount options=(suid) /b -> /2, mount options=(rw,suid) /c -> /3, mount options in (suid) /d -> /4, mount options in (ro,suid) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_6.sd0000644000175000017500000000043013502024172021235 0ustar jjjj# #=Description basic rules to test the "nosuid" mount option #=EXRESULT PASS /usr/bin/foo { mount options=nosuid /a -> /1, mount options=(nosuid) /b -> /2, mount options=(rw,nosuid) /c -> /3, mount options in (nosuid) /d -> /4, mount options in (ro,nosuid) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_30.sd0000644000175000017500000000040613502024172021315 0ustar jjjj# #=Description basic rules to test the "acl" mount option #=EXRESULT PASS /usr/bin/foo { mount options=acl /a -> /1, mount options=(acl) /b -> /2, mount options=(rw,acl) /c -> /3, mount options in (acl) /d -> /4, mount options in (ro,acl) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_37.sd0000644000175000017500000000043013502024172021321 0ustar jjjj# #=Description basic rules to test the "nouser" mount option #=EXRESULT PASS /usr/bin/foo { mount options=nouser /a -> /1, mount options=(nouser) /b -> /2, mount options=(rw,nouser) /c -> /3, mount options in (nouser) /d -> /4, mount options in (ro,nouser) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_outside_1.sd0000644000175000017500000000011413502024172022216 0ustar jjjj# #=Description mount rule outside of a profile #=EXRESULT FAIL # mount, apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_7.sd0000644000175000017500000000021713502024172021356 0ustar jjjj# #=Description basic rule to test the invalid "nodirsync" mount option #=EXRESULT FAIL /usr/bin/foo { mount options=(nodirsync) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_14.sd0000644000175000017500000000023513502024172021434 0ustar jjjj# #=Description basic rule to test the valid "rprivate" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(rprivate) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_34.sd0000644000175000017500000000044413502024172021323 0ustar jjjj# #=Description basic rules to test the "iversion" mount option #=EXRESULT PASS /usr/bin/foo { mount options=iversion /a -> /1, mount options=(iversion) /b -> /2, mount options=(rw,iversion) /c -> /3, mount options in (iversion) /d -> /4, mount options in (ro,iversion) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_22.sd0000644000175000017500000000012413502024172020431 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { remount /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_9.sd0000644000175000017500000000013213502024172020355 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount none -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_53.sd0000644000175000017500000000046313502024172021325 0ustar jjjj# #=Description basic rules to test the "make-rprivate" mount option #=EXRESULT PASS /usr/bin/foo { mount options=make-rprivate -> /1, mount options=(make-rprivate) -> /2, mount options=(rw,make-rprivate) -> /3, mount options in (make-rprivate) -> /4, mount options in (ro,make-rprivate) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_4.sd0000644000175000017500000000027113502024172021236 0ustar jjjj# #=Description basic rules to test the "rw" mount option #=EXRESULT PASS /usr/bin/foo { mount options=rw /a -> /1, mount options=(rw) /b -> /2, mount options in (rw) /d -> /4, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_19.sd0000644000175000017500000000024113502024172021436 0ustar jjjj# #=Description basic rule to test the valid "make-slave" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(make-slave) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_38.sd0000644000175000017500000000041413502024172021324 0ustar jjjj# #=Description basic rules to test the "user" mount option #=EXRESULT PASS /usr/bin/foo { mount options=user /a -> /1, mount options=(user) /b -> /2, mount options=(rw,user) /c -> /3, mount options in (user) /d -> /4, mount options in (ro,user) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/okay_7.sd0000644000175000017500000000013513502024172020710 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount /dev/** -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_13.sd0000644000175000017500000000024313502024172021432 0ustar jjjj# #=Description basic rule to test the valid "runbindable" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(runbindable) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_26.sd0000644000175000017500000000037213502024172021324 0ustar jjjj# #=Description basic rules to test the "M" mount option #=EXRESULT PASS /usr/bin/foo { mount options=M /a -> /1, mount options=(M) /b -> /2, mount options=(rw,M) /c -> /3, mount options in (M) /d -> /4, mount options in (ro,M) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_31.sd0000644000175000017500000000042213502024172021314 0ustar jjjj# #=Description basic rules to test the "noacl" mount option #=EXRESULT PASS /usr/bin/foo { mount options=noacl /a -> /1, mount options=(noacl) /b -> /2, mount options=(rw,noacl) /c -> /3, mount options in (noacl) /d -> /4, mount options in (ro,noacl) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_45.sd0000644000175000017500000000042513502024172021324 0ustar jjjj# #=Description basic rules to test the "rprivate" mount option #=EXRESULT PASS /usr/bin/foo { mount options=rprivate -> /1, mount options=(rprivate) -> /2, mount options=(rw,rprivate) -> /3, mount options in (rprivate) -> /4, mount options in (ro,rprivate) -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_29.sd0000644000175000017500000000041413502024172021324 0ustar jjjj# #=Description basic rules to test the "loud" mount option #=EXRESULT PASS /usr/bin/foo { mount options=loud /a -> /1, mount options=(loud) /b -> /2, mount options=(rw,loud) /c -> /3, mount options in (loud) /d -> /4, mount options in (ro,loud) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_8.sd0000644000175000017500000000023313502024172021355 0ustar jjjj# #=Description basic rule to test the valid "remount" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(remount) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_24.sd0000644000175000017500000000024513502024172021436 0ustar jjjj# #=Description basic rule to test the valid "make-rshared" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(make-rshared) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_12.sd0000644000175000017500000000023113502024172021426 0ustar jjjj# #=Description basic rule to test the valid "shared" mount opt and an invalid src #=EXRESULT FAIL /usr/bin/foo { mount options=(shared) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_2.sd0000644000175000017500000000012213502024172020345 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_13.sd0000644000175000017500000000042213502024172021314 0ustar jjjj# #=Description basic rules to test the "async" mount option #=EXRESULT PASS /usr/bin/foo { mount options=async /a -> /1, mount options=(async) /b -> /2, mount options=(rw,async) /c -> /3, mount options in (async) /d -> /4, mount options in (ro,async) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_17.sd0000644000175000017500000000014513502024172020440 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount options=(rw ro) -> /foo, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_opt_20.sd0000644000175000017500000000044413502024172021316 0ustar jjjj# #=Description basic rules to test the "diratime" mount option #=EXRESULT PASS /usr/bin/foo { mount options=diratime /a -> /1, mount options=(diratime) /b -> /2, mount options=(rw,diratime) /c -> /3, mount options in (diratime) /d -> /4, mount options in (ro,diratime) /e -> /5, } apparmor-2.13.3/parser/tst/simple_tests/mount/ok_1.sd0000644000175000017500000000011513502024172020346 0ustar jjjj# #=Description basic mount rule #=EXRESULT PASS # /usr/bin/foo { mount, } apparmor-2.13.3/parser/tst/simple_tests/mount/bad_opt_2.sd0000644000175000017500000000021313502024172021345 0ustar jjjj# #=Description basic rule to test the invalid "suidXXX" mount option #=EXRESULT FAIL /usr/bin/foo { mount options=(suidXXX) /a -> /1, } apparmor-2.13.3/parser/tst/simple_tests/include_tests/0000755000175000017500000000000013502024172020673 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_86.sd0000644000175000017500000000025013502024172022146 0ustar jjjj# #=DESCRIPTION include if exists testing - non-existent include should pass #=EXRESULT PASS # /does/not/exist { #include if exists "does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_26.sd0000644000175000017500000000027613502024172022150 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { #include "simple_tests/include_tests/includes with space helper.include" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_62.sd0000644000175000017500000000033513502024172022144 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { #include if exists "../tst/simple_tests/include_tests/includes_okay_helper.include" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ignored_suffix_2/0000755000175000017500000000000013502024172024127 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/include_tests/ignored_suffix_2/good.dpkg-new.include0000644000175000017500000000004313502024172030134 0ustar jjjj# Valid include @{FOO} = /foo /bar apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_64.sd0000644000175000017500000000050513502024172022145 0ustar jjjj# #=DESCRIPTION include if existss testing - test some "odd" locations of include if existss #=EXRESULT PASS # /does/not/exist { /does/not/exist mr, #include if exists /bin/true Px, #include if exists "../tst/simple_tests/include_tests/includes_okay_helper.include" #include if exists } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_11.sd0000644000175000017500000000027013502024172022134 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { #include "simple_tests/include_tests/includes_okay_helper.include" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/bad_1.sd0000644000175000017500000000022513502024172022170 0ustar jjjj# #=DESCRIPTION includes testing - non-existent include should fail #=EXRESULT FAIL # /does/not/exist { #include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_28.sd0000644000175000017500000000026313502024172022146 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { #include <"include_tests/includes with space helper.include"> } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_83.sd0000644000175000017500000000026413502024172022150 0ustar jjjj# #=DESCRIPTION include if exists testing - abs path include does not exist should pass #=EXRESULT PASS # /does/not/exist { #include if exists "/does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_87.sd0000644000175000017500000000025013502024172022147 0ustar jjjj# #=DESCRIPTION include if exists testing - non-existent include should pass #=EXRESULT PASS # /does/not/exist { #include if exists } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_78.sd0000644000175000017500000000032113502024172022146 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { #include if exists <"include_tests/includes with space helper.include"> } apparmor-2.13.3/parser/tst/simple_tests/include_tests/bad_14.sd0000644000175000017500000000026313502024172022256 0ustar jjjj# #=DESCRIPTION includes testing - non-existent include should fail #=EXRESULT FAIL # /does/not/exist { #include #include "../does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_3.sd0000644000175000017500000000026313502024172022057 0ustar jjjj# #=DESCRIPTION includes testing - basic include of a directory #=EXRESULT PASS # /does/not/exist { #include #include #include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_16.sd0000644000175000017500000000026613502024172022146 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { #include simple_tests/include_tests/includes_okay_helper.include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_70.sd0000644000175000017500000000036013502024172022141 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of a directory #=EXRESULT PASS # /does/not/exist { #include if exists #include if exists simple_tests/includes/ #include if exists } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_82.sd0000644000175000017500000000024713502024172022150 0ustar jjjj# #=DESCRIPTION include if exist testing - non-existent include should pass #=EXRESULT PASS # /does/not/exist { #include if exists "does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_12.sd0000644000175000017500000000027713502024172022144 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { #include "../tst/simple_tests/include_tests/includes_okay_helper.include" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_69.sd0000644000175000017500000000050313502024172022150 0ustar jjjj# #=DESCRIPTION include if existss testing - test some "odd" locations of include if existss #=EXRESULT PASS # /does/not/exist { /does/not/exist mr, #include if exists /bin/true Px, #include if exists ../tst/simple_tests/include_tests/includes_okay_helper.include #include if exists } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_65.sd0000644000175000017500000000036213502024172022147 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of a directory #=EXRESULT PASS # /does/not/exist { #include if exists #include if exists "simple_tests/includes/" #include if exists } apparmor-2.13.3/parser/tst/simple_tests/include_tests/bad_4.sd0000644000175000017500000000026013502024172022172 0ustar jjjj# #=DESCRIPTION includes testing - non-existent include should fail #=EXRESULT FAIL # /does/not/exist { #include #include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_15.sd0000644000175000017500000000030013502024172022132 0ustar jjjj# #=DESCRIPTION includes testing - basic include of a directory #=EXRESULT PASS # /does/not/exist { #include #include "simple_tests/includes/" #include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_66.sd0000644000175000017500000000032413502024172022146 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { #include if exists simple_tests/include_tests/includes_okay_helper.include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/bad_12.sd0000644000175000017500000000022513502024172022252 0ustar jjjj# #=DESCRIPTION includes testing - mis-parsing include should fail #=EXRESULT FAIL # /does/not/exist { #include "/does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/includes with space helper.include0000644000175000017500000000013213502024172027312 0ustar jjjj# #=DESCRIPTION A helper for includes_okay.sd # #include /tmp/** r, apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_31.sd0000644000175000017500000000027513502024172022143 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { #include #comment } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_19.sd0000644000175000017500000000042113502024172022142 0ustar jjjj# #=DESCRIPTION includes testing - test some "odd" locations of includes #=EXRESULT PASS # /does/not/exist { /does/not/exist mr, #include /bin/true Px, #include ../tst/simple_tests/include_tests/includes_okay_helper.include #include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_88.sd0000644000175000017500000000030313502024172022147 0ustar jjjj# #=DESCRIPTION include if exists testing - non-existent include should pass #=EXRESULT PASS # /does/not/exist { #include if exists #include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_76.sd0000644000175000017500000000033413502024172022150 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { #include if exists "simple_tests/include_tests/includes with space helper.include" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ignored_suffix_2.sd0000644000175000017500000000024713502024172024462 0ustar jjjj# #=DESCRIPTION includes testing - verify that only suffixes are ignored #=EXRESULT PASS # #include /does/not/exist { @{FOO} r, } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ignored_suffix/0000755000175000017500000000000013502024172023706 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/include_tests/ignored_suffix/bad-include.dpkg-dist0000644000175000017500000000002513502024172027662 0ustar jjjjTHIS WILL NOT PARSE! apparmor-2.13.3/parser/tst/simple_tests/include_tests/ignored_suffix/.bad-include0000644000175000017500000000002513502024172026053 0ustar jjjjTHIS WILL NOT PARSE! apparmor-2.13.3/parser/tst/simple_tests/include_tests/ignored_suffix/bad-include.dpkg-old0000644000175000017500000000002513502024172027475 0ustar jjjjTHIS WILL NOT PARSE! apparmor-2.13.3/parser/tst/simple_tests/include_tests/ignored_suffix/bad-include.dpkg-new0000644000175000017500000000002513502024172027510 0ustar jjjjTHIS WILL NOT PARSE! apparmor-2.13.3/parser/tst/simple_tests/include_tests/ignored_suffix/bad-include.dpkg-bak0000644000175000017500000000002513502024172027454 0ustar jjjjTHIS WILL NOT PARSE! apparmor-2.13.3/parser/tst/simple_tests/include_tests/ignored_suffix/good-include0000644000175000017500000000004313502024172026177 0ustar jjjj# Valid include @{FOO} = /foo /bar apparmor-2.13.3/parser/tst/simple_tests/include_tests/ignored_suffix/bad-include.rpmnew0000644000175000017500000000002513502024172027304 0ustar jjjjTHIS WILL NOT PARSE! apparmor-2.13.3/parser/tst/simple_tests/include_tests/ignored_suffix/bad-include~0000644000175000017500000000002513502024172026173 0ustar jjjjTHIS WILL NOT PARSE! apparmor-2.13.3/parser/tst/simple_tests/include_tests/ignored_suffix/bad-include.rpmsave0000644000175000017500000000002513502024172027451 0ustar jjjjTHIS WILL NOT PARSE! apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_14.sd0000644000175000017500000000042313502024172022137 0ustar jjjj# #=DESCRIPTION includes testing - test some "odd" locations of includes #=EXRESULT PASS # /does/not/exist { /does/not/exist mr, #include /bin/true Px, #include "../tst/simple_tests/include_tests/includes_okay_helper.include" #include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ignored_suffix_1.sd0000644000175000017500000000025013502024172024453 0ustar jjjj# #=DESCRIPTION includes testing - verify that ignored suffixes are ignored #=EXRESULT PASS # #include /does/not/exist { @{FOO} r, } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_63.sd0000644000175000017500000000033013502024172022140 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { #include if exists "./simple_tests/include_tests/includes_okay_helper.include" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_20.sd0000644000175000017500000000027613502024172022142 0ustar jjjj# #=DESCRIPTION includes testing - basic include of a directory #=EXRESULT PASS # /does/not/exist { #include #include simple_tests/includes/ #include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_18.sd0000644000175000017500000000027013502024172022143 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { #include ./simple_tests/include_tests/includes_okay_helper.include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_79.sd0000644000175000017500000000033313502024172022152 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { #include if exists <"include_tests/includes with space helper.include"> #comment } apparmor-2.13.3/parser/tst/simple_tests/include_tests/recursive.sd0000644000175000017500000000021713502024172023232 0ustar jjjj# #=DESCRIPTION includes testing - recursive include should fail #=EXRESULT FAIL # /does/not/exist { #include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_77.sd0000644000175000017500000000034613502024172022154 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { #include if exists "simple_tests/include_tests/includes with space helper.include" #comment } apparmor-2.13.3/parser/tst/simple_tests/include_tests/includes_okay_helper.include0000644000175000017500000000013213502024172026424 0ustar jjjj# #=DESCRIPTION A helper for includes_okay.sd # #include /tmp/** r, apparmor-2.13.3/parser/tst/simple_tests/include_tests/bad_13.sd0000644000175000017500000000026013502024172022252 0ustar jjjj# #=DESCRIPTION includes testing - non-existent include should fail #=EXRESULT FAIL # /does/not/exist { #include "does-not-exist/does-not-exist" #include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_81.sd0000644000175000017500000000033313502024172022143 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { #include if exists #comment } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_67.sd0000644000175000017500000000033313502024172022147 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { #include if exists ../tst/simple_tests/include_tests/includes_okay_helper.include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_13.sd0000644000175000017500000000027213502024172022140 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { #include "./simple_tests/include_tests/includes_okay_helper.include" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/bad_11.sd0000644000175000017500000000022513502024172022251 0ustar jjjj# #=DESCRIPTION includes testing - non-existent include should fail #=EXRESULT FAIL # /does/not/exist { #include "does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_80.sd0000644000175000017500000000031713502024172022144 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { #include if exists } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_84.sd0000644000175000017500000000030613502024172022146 0ustar jjjj# #=DESCRIPTION include if exists testing - non-existent include should pass #=EXRESULT PASS # /does/not/exist { #include #include if exists "../does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_61.sd0000644000175000017500000000032613502024172022143 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { #include if exists "simple_tests/include_tests/includes_okay_helper.include" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_30.sd0000644000175000017500000000026113502024172022135 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { #include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/bad_2.sd0000644000175000017500000000022213502024172022166 0ustar jjjj# #=DESCRIPTION includes testing - mis-parsing include should fail #=EXRESULT FAIL # /does/not/exist { #include does-not-exist/does-not-exist } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_27.sd0000644000175000017500000000031013502024172022136 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { #include "simple_tests/include_tests/includes with space helper.include" #comment } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_85.sd0000644000175000017500000000030613502024172022147 0ustar jjjj# #=DESCRIPTION include if exists testing - non-existent include should pass #=EXRESULT PASS # /does/not/exist { #include #include if exists "../does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_2.sd0000644000175000017500000000037713502024172022064 0ustar jjjj# #=DESCRIPTION includes testing - test some "odd" locations of includes #=EXRESULT PASS # /does/not/exist { /does/not/exist mr, #include /bin/true Px, #include #include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/bad_15.sd0000644000175000017500000000022513502024172022255 0ustar jjjj# #=DESCRIPTION includes testing - non-existent include should fail #=EXRESULT FAIL # /does/not/exist { #include "does-not-exist/does-not-exist" } apparmor-2.13.3/parser/tst/simple_tests/include_tests/bad_3.sd0000644000175000017500000000026013502024172022171 0ustar jjjj# #=DESCRIPTION includes testing - non-existent include should fail #=EXRESULT FAIL # /does/not/exist { #include #include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_29.sd0000644000175000017500000000027513502024172022152 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { #include <"include_tests/includes with space helper.include"> #comment } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_17.sd0000644000175000017500000000027513502024172022147 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { #include ../tst/simple_tests/include_tests/includes_okay_helper.include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_1.sd0000644000175000017500000000034113502024172022052 0ustar jjjj# #=DESCRIPTION includes testing - basic include of global and local include #=EXRESULT PASS # /does/not/exist { #include #include #include } apparmor-2.13.3/parser/tst/simple_tests/include_tests/ok_68.sd0000644000175000017500000000032613502024172022152 0ustar jjjj# #=DESCRIPTION include if existss testing - basic include if exists of global and local include #=EXRESULT PASS # /does/not/exist { #include if exists ./simple_tests/include_tests/includes_okay_helper.include } apparmor-2.13.3/parser/tst/simple_tests/includes-preamble/0000755000175000017500000000000013502024172021421 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/includes-preamble/aliases0000644000175000017500000000006313502024172022764 0ustar jjjjalias /usr/ -> /User/, alias /lib/ -> /Libraries/, apparmor-2.13.3/parser/tst/simple_tests/includes-preamble/vars0000644000175000017500000000011613502024172022315 0ustar jjjj# variable declarations for inclusion @{FOO} = /foo /bar /baz /biff /lib /tmp apparmor-2.13.3/parser/tst/simple_tests/capability/0000755000175000017500000000000013502024172020147 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/capability/bad_1.sd0000644000175000017500000000024413502024172021445 0ustar jjjj# #=DESCRIPTION fail CAP_XXX syntax. #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { capability CAP_CHOWN, } apparmor-2.13.3/parser/tst/simple_tests/capability/set/0000755000175000017500000000000013502024172020742 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/capability/set/ok1.sd0000644000175000017500000000721613502024172021772 0ustar jjjj# #=DESCRIPTION validate some uses of capabilties. #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { set capability chown, set capability dac_override, set capability dac_read_search, set capability fowner, set capability fsetid, set capability kill, set capability setgid, set capability setuid, set capability setpcap, set capability linux_immutable, set capability net_bind_service, set capability net_broadcast, set capability net_admin, set capability net_raw, set capability ipc_lock, set capability ipc_owner, set capability sys_module, set capability sys_rawio, set capability sys_chroot, set capability sys_ptrace, set capability sys_pacct, set capability sys_admin, set capability sys_boot, set capability sys_nice, set capability sys_resource, set capability sys_time, set capability sys_tty_config, set capability mknod, set capability lease, set capability audit_write, set capability audit_control, } /does/not/exist2 { ^chown { set capability chown, } ^dac_override { set capability dac_override, } ^dac_read_search { set capability dac_read_search, } ^fowner { set capability fowner, } ^fsetid { set capability fsetid, } ^kill { set capability kill, } ^setgid { set capability setgid, } ^setuid { set capability setuid, } ^setpcap { set capability setpcap, } ^linux_immutable { set capability linux_immutable, } ^net_bind_service { set capability net_bind_service, } ^net_broadcast { set capability net_broadcast, } ^net_admin { set capability net_admin, } ^net_raw { set capability net_raw, } ^ipc_lock { set capability ipc_lock, } ^ipc_owner { set capability ipc_owner, } ^sys_module { set capability sys_module, } ^sys_rawio { set capability sys_rawio, } ^sys_chroot { set capability sys_chroot, } ^sys_ptrace { set capability sys_ptrace, } ^sys_pacct { set capability sys_pacct, } ^sys_admin { set capability sys_admin, } ^sys_boot { set capability sys_boot, } ^sys_nice { set capability sys_nice, } ^sys_resource { set capability sys_resource, } ^sys_time { set capability sys_time, } ^sys_tty_config { set capability sys_tty_config, } ^mknod { set capability mknod, } ^lease { set capability lease, } ^audit_write { set capability audit_write, } ^audit_control { set capability audit_control, } } # Test for duplicates? /does/not/exist3 { set capability mknod, set capability mknod, } /does/not/exit101 { set capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, } /does/not/exit102 { set capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, set capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, } apparmor-2.13.3/parser/tst/simple_tests/capability/ok_allow10.sd0000644000175000017500000000033113502024172022444 0ustar jjjj# #=DESCRIPTION validate audit allow with bare capability in hat. #=EXRESULT PASS # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { ^capability { audit allow capability, } } apparmor-2.13.3/parser/tst/simple_tests/capability/ok2.sd0000644000175000017500000000761213502024172021200 0ustar jjjj# #=DESCRIPTION validate some uses of capabilties. #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { audit capability chown, audit capability dac_override, audit capability dac_read_search, audit capability fowner, audit capability fsetid, audit capability kill, audit capability setgid, audit capability setuid, audit capability setpcap, audit capability linux_immutable, audit capability net_bind_service, audit capability net_broadcast, audit capability net_admin, audit capability net_raw, audit capability ipc_lock, audit capability ipc_owner, audit capability sys_module, audit capability sys_rawio, audit capability sys_chroot, audit capability sys_ptrace, audit capability sys_pacct, audit capability sys_admin, audit capability sys_boot, audit capability sys_nice, audit capability sys_resource, audit capability sys_time, audit capability sys_tty_config, audit capability mknod, audit capability lease, audit capability audit_write, audit capability audit_control, audit capability setfcap, audit capability mac_override, } /does/not/exist2 { ^chown { deny capability chown, } ^dac_override { deny capability dac_override, } ^dac_read_search { deny capability dac_read_search, } ^fowner { deny capability fowner, } ^fsetid { deny capability fsetid, } ^kill { deny capability kill, } ^setgid { deny capability setgid, } ^setuid { deny capability setuid, } ^setpcap { deny capability setpcap, } ^linux_immutable { deny capability linux_immutable, } ^net_bind_service { deny capability net_bind_service, } ^net_broadcast { deny capability net_broadcast, } ^net_admin { deny capability net_admin, } ^net_raw { deny capability net_raw, } ^ipc_lock { deny capability ipc_lock, } ^ipc_owner { deny capability ipc_owner, } ^sys_module { deny capability sys_module, } ^sys_rawio { deny capability sys_rawio, } ^sys_chroot { deny capability sys_chroot, } ^sys_ptrace { deny capability sys_ptrace, } ^sys_pacct { deny capability sys_pacct, } ^sys_admin { deny capability sys_admin, } ^sys_boot { deny capability sys_boot, } ^sys_nice { deny capability sys_nice, } ^sys_resource { deny capability sys_resource, } ^sys_time { deny capability sys_time, } ^sys_tty_config { deny capability sys_tty_config, } ^mknod { deny capability mknod, } ^lease { deny capability lease, } ^audit_write { deny capability audit_write, } ^audit_control { deny capability audit_control, } } # Test for duplicates? /does/not/exist3 { capability mknod, audit capability mknod, deny capability mknod, audit capability mknod, deny capability mknod, capability mknod, } /does/not/exit101 { capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, } /does/not/exit102 { audit deny capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, deny capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, } apparmor-2.13.3/parser/tst/simple_tests/capability/ok_allow4.sd0000644000175000017500000000250613502024172022375 0ustar jjjj# #=DESCRIPTION validate audit allow w/capabilities. #=EXRESULT PASS # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { audit allow capability chown, audit allow capability dac_override, audit allow capability dac_read_search, audit allow capability fowner, audit allow capability fsetid, audit allow capability kill, audit allow capability setgid, audit allow capability setuid, audit allow capability setpcap, audit allow capability linux_immutable, audit allow capability net_bind_service, audit allow capability net_broadcast, audit allow capability net_admin, audit allow capability net_raw, audit allow capability ipc_lock, audit allow capability ipc_owner, audit allow capability sys_module, audit allow capability sys_rawio, audit allow capability sys_chroot, audit allow capability sys_ptrace, audit allow capability sys_pacct, audit allow capability sys_admin, audit allow capability sys_boot, audit allow capability sys_nice, audit allow capability sys_resource, audit allow capability sys_time, audit allow capability sys_tty_config, audit allow capability mknod, audit allow capability lease, audit allow capability audit_write, audit allow capability audit_control, audit allow capability setfcap, audit allow capability mac_override, } apparmor-2.13.3/parser/tst/simple_tests/capability/bad_5.sd0000644000175000017500000000027113502024172021451 0ustar jjjj# #=DESCRIPTION fail conflicting perm mod same line #=EXRESULT FAIL # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { allow deny capability chown, } apparmor-2.13.3/parser/tst/simple_tests/capability/bad_6.sd0000644000175000017500000000027713502024172021460 0ustar jjjj# #=DESCRIPTION fail conflicting perm mod same line #=EXRESULT FAIL # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { audit allow deny capability chown, } apparmor-2.13.3/parser/tst/simple_tests/capability/ok1.sd0000644000175000017500000000672013502024172021176 0ustar jjjj# #=DESCRIPTION validate some uses of capabilties. #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { capability chown, capability dac_override, capability dac_read_search, capability fowner, capability fsetid, capability kill, capability setgid, capability setuid, capability setpcap, capability linux_immutable, capability net_bind_service, capability net_broadcast, capability net_admin, capability net_raw, capability ipc_lock, capability ipc_owner, capability sys_module, capability sys_rawio, capability sys_chroot, capability sys_ptrace, capability sys_pacct, capability sys_admin, capability sys_boot, capability sys_nice, capability sys_resource, capability sys_time, capability sys_tty_config, capability mknod, capability lease, capability audit_write, capability audit_control, capability setfcap, capability mac_override, } /does/not/exist2 { ^chown { capability chown, } ^dac_override { capability dac_override, } ^dac_read_search { capability dac_read_search, } ^fowner { capability fowner, } ^fsetid { capability fsetid, } ^kill { capability kill, } ^setgid { capability setgid, } ^setuid { capability setuid, } ^setpcap { capability setpcap, } ^linux_immutable { capability linux_immutable, } ^net_bind_service { capability net_bind_service, } ^net_broadcast { capability net_broadcast, } ^net_admin { capability net_admin, } ^net_raw { capability net_raw, } ^ipc_lock { capability ipc_lock, } ^ipc_owner { capability ipc_owner, } ^sys_module { capability sys_module, } ^sys_rawio { capability sys_rawio, } ^sys_chroot { capability sys_chroot, } ^sys_ptrace { capability sys_ptrace, } ^sys_pacct { capability sys_pacct, } ^sys_admin { capability sys_admin, } ^sys_boot { capability sys_boot, } ^sys_nice { capability sys_nice, } ^sys_resource { capability sys_resource, } ^sys_time { capability sys_time, } ^sys_tty_config { capability sys_tty_config, } ^mknod { capability mknod, } ^lease { capability lease, } ^audit_write { capability audit_write, } ^audit_control { capability audit_control, } } # Test for duplicates? /does/not/exist3 { capability mknod, capability mknod, } /does/not/exit101 { capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, } /does/not/exit102 { capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, } apparmor-2.13.3/parser/tst/simple_tests/capability/ok_allow8.sd0000644000175000017500000000031513502024172022375 0ustar jjjj# #=DESCRIPTION validate allow with bare capability in hat. #=EXRESULT PASS # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { ^capability { allow capability, } } apparmor-2.13.3/parser/tst/simple_tests/capability/ok_allow2.sd0000644000175000017500000000333413502024172022373 0ustar jjjj# #=DESCRIPTION validate uses of allow/capabilities in hats #=EXRESULT PASS # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist2 { ^chown { allow capability chown, } ^dac_override { allow capability dac_override, } ^dac_read_search { allow capability dac_read_search, } ^fowner { allow capability fowner, } ^fsetid { allow capability fsetid, } ^kill { allow capability kill, } ^setgid { allow capability setgid, } ^setuid { allow capability setuid, } ^setpcap { allow capability setpcap, } ^linux_immutable { allow capability linux_immutable, } ^net_bind_service { allow capability net_bind_service, } ^net_broadcast { allow capability net_broadcast, } ^net_admin { allow capability net_admin, } ^net_raw { allow capability net_raw, } ^ipc_lock { allow capability ipc_lock, } ^ipc_owner { allow capability ipc_owner, } ^sys_module { allow capability sys_module, } ^sys_rawio { allow capability sys_rawio, } ^sys_chroot { allow capability sys_chroot, } ^sys_ptrace { allow capability sys_ptrace, } ^sys_pacct { allow capability sys_pacct, } ^sys_admin { allow capability sys_admin, } ^sys_boot { allow capability sys_boot, } ^sys_nice { allow capability sys_nice, } ^sys_resource { allow capability sys_resource, } ^sys_time { allow capability sys_time, } ^sys_tty_config { allow capability sys_tty_config, } ^mknod { allow capability mknod, } ^lease { allow capability lease, } ^audit_write { allow capability audit_write, } ^audit_control { allow capability audit_control, } } apparmor-2.13.3/parser/tst/simple_tests/capability/ok_dup_allow3.sd0000644000175000017500000000152013502024172023237 0ustar jjjj# #=DESCRIPTION validate allow of duplicate multiple capabilities. #=EXRESULT PASS # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exit102 { allow capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, allow capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, } apparmor-2.13.3/parser/tst/simple_tests/capability/bad_4.sd0000644000175000017500000000024713502024172021453 0ustar jjjj# #=DESCRIPTION fail unknown keyword #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { capability chown foobar, } apparmor-2.13.3/parser/tst/simple_tests/capability/ok_dup_allow5.sd0000644000175000017500000000301013502024172023235 0ustar jjjj# #=DESCRIPTION validate duplicate multiple capabilities w/differing perm mods. #=EXRESULT PASS # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exit102 { allow capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, audit allow capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, audit deny capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, deny capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, } apparmor-2.13.3/parser/tst/simple_tests/capability/ok_allow6.sd0000644000175000017500000000077613502024172022406 0ustar jjjj# #=DESCRIPTION validate audit allow w/multiple capabilities. #=EXRESULT PASS # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exit101 { audit allow capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, } apparmor-2.13.3/parser/tst/simple_tests/capability/ok_allow7.sd0000644000175000017500000000026613502024172022401 0ustar jjjj# #=DESCRIPTION validate allow with bare capability keyword. #=EXRESULT PASS # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { allow capability, } apparmor-2.13.3/parser/tst/simple_tests/capability/ok_allow3.sd0000644000175000017500000000077413502024172022401 0ustar jjjj# #=DESCRIPTION validate allow w/multiple capabilities in a line. #=EXRESULT PASS # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exit101 { allow capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, } apparmor-2.13.3/parser/tst/simple_tests/capability/ok_dup_allow1.sd0000644000175000017500000000035513502024172023242 0ustar jjjj# #=DESCRIPTION validate allow of duplicate capabilities. #=EXRESULT PASS # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # # Test for duplicates? /does/not/exist3 { allow capability mknod, allow capability mknod, } apparmor-2.13.3/parser/tst/simple_tests/capability/ok_dup_allow4.sd0000644000175000017500000000154213502024172023244 0ustar jjjj# #=DESCRIPTION validate audit allow of duplicate multiple capabilities. #=EXRESULT PASS # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exit102 { audit allow capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, audit allow capability chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control, } apparmor-2.13.3/parser/tst/simple_tests/capability/bad_outside1.sd0000644000175000017500000000012513502024172023040 0ustar jjjj# #=DESCRIPTION capability rule outside of a profile #=EXRESULT FAIL # capability, apparmor-2.13.3/parser/tst/simple_tests/capability/bad_2.sd0000644000175000017500000000024113502024172021443 0ustar jjjj# #=DESCRIPTION fail unknown keyword #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { capability foobar, } apparmor-2.13.3/parser/tst/simple_tests/capability/ok3.sd0000644000175000017500000000024713502024172021176 0ustar jjjj# #=DESCRIPTION validate some uses of capabilties. #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { capability, } apparmor-2.13.3/parser/tst/simple_tests/capability/ok_allow9.sd0000644000175000017500000000030213502024172022372 0ustar jjjj# #=DESCRIPTION validate audit allow with bare capability keyword. #=EXRESULT PASS # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { audit allow capability, } apparmor-2.13.3/parser/tst/simple_tests/capability/bad_3.sd0000644000175000017500000000025213502024172021446 0ustar jjjj# #=DESCRIPTION fail CAP_XXX syntax. #=EXRESULT FAIL # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { capability chown CAP_CHOWN, } apparmor-2.13.3/parser/tst/simple_tests/capability/ok_allow5.sd0000644000175000017500000000363013502024172022375 0ustar jjjj# #=DESCRIPTION validate audit allow w/capabilities in hats. #=EXRESULT PASS # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist2 { ^chown { audit allow capability chown, } ^dac_override { audit allow capability dac_override, } ^dac_read_search { audit allow capability dac_read_search, } ^fowner { audit allow capability fowner, } ^fsetid { audit allow capability fsetid, } ^kill { audit allow capability kill, } ^setgid { audit allow capability setgid, } ^setuid { audit allow capability setuid, } ^setpcap { audit allow capability setpcap, } ^linux_immutable { audit allow capability linux_immutable, } ^net_bind_service { audit allow capability net_bind_service, } ^net_broadcast { audit allow capability net_broadcast, } ^net_admin { audit allow capability net_admin, } ^net_raw { audit allow capability net_raw, } ^ipc_lock { audit allow capability ipc_lock, } ^ipc_owner { audit allow capability ipc_owner, } ^sys_module { audit allow capability sys_module, } ^sys_rawio { audit allow capability sys_rawio, } ^sys_chroot { audit allow capability sys_chroot, } ^sys_ptrace { audit allow capability sys_ptrace, } ^sys_pacct { audit allow capability sys_pacct, } ^sys_admin { audit allow capability sys_admin, } ^sys_boot { audit allow capability sys_boot, } ^sys_nice { audit allow capability sys_nice, } ^sys_resource { audit allow capability sys_resource, } ^sys_time { audit allow capability sys_time, } ^sys_tty_config { audit allow capability sys_tty_config, } ^mknod { audit allow capability mknod, } ^lease { audit allow capability lease, } ^audit_write { audit allow capability audit_write, } ^audit_control { audit allow capability audit_control, } } apparmor-2.13.3/parser/tst/simple_tests/capability/ok_allow1.sd0000644000175000017500000000220013502024172022361 0ustar jjjj# #=DESCRIPTION validate uses of allow/capabilities. #=EXRESULT PASS # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { allow capability chown, allow capability dac_override, allow capability dac_read_search, allow capability fowner, allow capability fsetid, allow capability kill, allow capability setgid, allow capability setuid, allow capability setpcap, allow capability linux_immutable, allow capability net_bind_service, allow capability net_broadcast, allow capability net_admin, allow capability net_raw, allow capability ipc_lock, allow capability ipc_owner, allow capability sys_module, allow capability sys_rawio, allow capability sys_chroot, allow capability sys_ptrace, allow capability sys_pacct, allow capability sys_admin, allow capability sys_boot, allow capability sys_nice, allow capability sys_resource, allow capability sys_time, allow capability sys_tty_config, allow capability mknod, allow capability lease, allow capability audit_write, allow capability audit_control, allow capability setfcap, allow capability mac_override, } apparmor-2.13.3/parser/tst/simple_tests/capability/ok_dup_allow2.sd0000644000175000017500000000037713502024172023247 0ustar jjjj# #=DESCRIPTION validate audit allow of duplicate capabilities. #=EXRESULT PASS # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # # Test for duplicates? /does/not/exist3 { audit allow capability mknod, audit allow capability mknod, } apparmor-2.13.3/parser/tst/simple_tests/capability/ok_dup_allow6.sd0000644000175000017500000000052613502024172023247 0ustar jjjj# #=DESCRIPTION validate duplicate capability entries. #=EXRESULT PASS # vim:syntax=apparmor # Last Modified: Sun Apr 17 19:44:44 2005 # # Test for duplicates? /does/not/exist3 { capability mknod, audit allow capability mknod, deny capability mknod, audit allow capability mknod, deny capability mknod, allow capability mknod, } apparmor-2.13.3/parser/tst/simple_tests/change_hat/0000755000175000017500000000000013502024172020107 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/change_hat/new_style3.sd0000644000175000017500000000064313502024172022536 0ustar jjjj# #=DESCRIPTION Simple test of new-style hats with spaces #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { #include # hat 1 ^HAT1 { /var/log/HAT1 rwl, } # hat 2 ^HAT2 { /var/log/HAT2 rwl, } # hat 3 ^HAT3 { /var/log/HAT3 rwl, } /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } apparmor-2.13.3/parser/tst/simple_tests/change_hat/new_style1.sd0000644000175000017500000000055513502024172022536 0ustar jjjj# #=DESCRIPTION Simple test of new-style hats #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { #include # hat 1 ^HAT1 { /var/log/HAT1 rwl, } # hat 2 ^HAT2 { /var/log/HAT2 rwl, } # hat 3 ^HAT3 { /var/log/HAT3 rwl, } /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } apparmor-2.13.3/parser/tst/simple_tests/change_hat/new_style4.sd0000644000175000017500000000064613502024172022542 0ustar jjjj# #=DESCRIPTION Simple test of new-style hats #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } # hat 1 hat /does/not/exist//HAT1 { /var/log/HAT1 rwl, } # hat 2 hat /does/not/exist//HAT2 { /var/log/HAT2 rwl, } # hat 3 hat /does/not/exist//HAT3 { /var/log/HAT3 rwl, } apparmor-2.13.3/parser/tst/simple_tests/change_hat/new_style2.sd0000644000175000017500000000151613502024172022535 0ustar jjjj# #=DESCRIPTION Tests to verify multiple profiles can have the same hatname #=EXRESULT PASS # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /HAT1 { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } /HAT2 { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } /HAT3 { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } /does/not/exist1 { #include # hat 1 ^/HAT1 { /var/log/HAT1 rwl, } # hat 2 ^/HAT2 { /var/log/HAT2 rwl, } } /does/not/exist2 { #include # hat 1 ^/HAT1 { /var/log/HAT1 rwl, } # hat 2 ^/HAT2 { /var/log/HAT2 rwl, } } /does/not/exist3 { #include # hat 1 ^/HAT1 { /var/log/HAT1 rwl, } # hat 2 ^/HAT3 { /var/log/HAT2 rwl, } } apparmor-2.13.3/parser/tst/simple_tests/change_hat/bad_parsing.sd0000644000175000017500000000023013502024172022703 0ustar jjjj# #=DESCRIPTION A simple syntax error -- missing hatname + bad parsing #=EXRESULT FAIL # /usr/bin/foo^!!!!!!!!!^BLAH { /blah rw, } /usr/bin/foo { } apparmor-2.13.3/parser/tst/simple_tests/change_hat/old_style1.sd0000644000175000017500000000062113502024172022515 0ustar jjjj# #=DESCRIPTION Simple test of old-style hats #=EXRESULT FAIL #=DISABLED # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # /does/not/exist { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } # hat 1 /does/not/exist^HAT1 { /var/log/HAT1 rwl, } # hat 2 /does/not/exist^HAT2 { /var/log/HAT2 rwl, } # hat 3 /does/not/exist^HAT3 { /var/log/HAT3 rwl, } apparmor-2.13.3/parser/tst/simple_tests/change_hat/old_style3.sd0000644000175000017500000000061613502024172022523 0ustar jjjj# #=DESCRIPTION Simple test of old-style hats #=EXRESULT FAIL #=DISABLED # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # hat /does/not/exist^HAT { /var/log/HAT rwl, } # hat 0 /does/not/exist^HAT0 { /var/log/HAT0 rwl, } # hat 1 /does/not/exist^HAT1 { /var/log/HAT1 rwl, } /does/not/exist { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } apparmor-2.13.3/parser/tst/simple_tests/change_hat/old_style2.sd0000644000175000017500000000077313502024172022526 0ustar jjjj# #=DESCRIPTION Simple test of old-style hats #=EXRESULT FAIL #=DISABLED # vim:syntax=subdomain # Last Modified: Sun Apr 17 19:44:44 2005 # hat /does/not/exist^HAT { /var/log/HAT rwl, } # hat 0 /does/not/exist^HAT0 { /var/log/HAT0 rwl, } /does/not/exist { #include /usr/X11R6/lib/lib*so* r, /usr/bin/emacs r, } # hat 1 /does/not/exist^HAT1 { /var/log/HAT1 rwl, } # hat 2 /does/not/exist^HAT2 { /var/log/HAT2 rwl, } # hat 3 /does/not/exist^HAT3 { /var/log/HAT3 rwl, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/0000755000175000017500000000000013502024172017511 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_06.sd0000644000175000017500000000023313502024172022335 0ustar jjjj# #=DESCRIPTION simple core file size rlimit test #=EXRESULT PASS profile rlimit { set rlimit core <= 44444KB, # 4 chosen by completely fair die roll } apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_18.sd0000644000175000017500000000016713502024172022346 0ustar jjjj# #=DESCRIPTION simple realtime time rlimit test #=EXRESULT PASS profile rlimit { set rlimit rttime <= 60minutes, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_10.sd0000644000175000017500000000017213502024172022332 0ustar jjjj# #=DESCRIPTION simple max virtual memory szie rlimit test #=EXRESULT PASS profile rlimit { set rlimit as <= 2047MB, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_07.sd0000644000175000017500000000015113502024172022335 0ustar jjjj# #=DESCRIPTION simple rss rlimit test #=EXRESULT PASS profile rlimit { set rlimit rss <= infinity, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_01.sd0000644000175000017500000000017713502024172022337 0ustar jjjj# #=DESCRIPTION simple cpu rlimit test, cpu allows default units #=EXRESULT PASS profile rlimit { set rlimit cpu <= 1024, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_02.sd0000644000175000017500000000015113502024172022330 0ustar jjjj# #=DESCRIPTION simple cpu rlimit test #=EXRESULT PASS profile rlimit { set rlimit cpu <= infinity, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_09.sd0000644000175000017500000000020213502024172022334 0ustar jjjj# #=DESCRIPTION simple max open file (same as nofile) rlimit test #=EXRESULT PASS profile rlimit { set rlimit ofile <= 1234, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_05.sd0000644000175000017500000000016013502024172022333 0ustar jjjj# #=DESCRIPTION simple stack size rlimit test #=EXRESULT PASS profile rlimit { set rlimit stack <= 1024GB, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_17.sd0000644000175000017500000000015113502024172022336 0ustar jjjj# #=DESCRIPTION simple rtprio rlimit test #=EXRESULT PASS profile rlimit { set rlimit rtprio <= 10, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_15.sd0000644000175000017500000000016113502024172022335 0ustar jjjj# #=DESCRIPTION simple sigpending rlimit test #=EXRESULT PASS profile rlimit { set rlimit sigpending <= 42, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_13.sd0000644000175000017500000000017113502024172022334 0ustar jjjj# #=DESCRIPTION simple rttime rlimit allows default units #=EXRESULT PASS profile rlimit { set rlimit rttime <= 12, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_14.sd0000644000175000017500000000015713502024172022341 0ustar jjjj# #=DESCRIPTION simple msgqueue rlimit test #=EXRESULT PASS profile rlimit { set rlimit msgqueue <= 4444, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_12.sd0000644000175000017500000000015613502024172022336 0ustar jjjj# #=DESCRIPTION simple memlock rlimit test #=EXRESULT PASS profile rlimit { set rlimit memlock <= 10240, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_16.sd0000644000175000017500000000014613502024172022341 0ustar jjjj# #=DESCRIPTION simple nice rlimit test #=EXRESULT PASS profile rlimit { set rlimit nice <= -10, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/bad_rlimit_outside_01.sd0000644000175000017500000000014513502024172024203 0ustar jjjj# #=DESCRIPTION simple cpu rlimit rule outside of a profile #=EXRESULT FAIL set rlimit cpu <= 1024, apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_03.sd0000644000175000017500000000015713502024172022337 0ustar jjjj# #=DESCRIPTION simple file size rlimit test #=EXRESULT PASS profile rlimit { set rlimit fsize <= 1023MB, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_04.sd0000644000175000017500000000016113502024172022333 0ustar jjjj# #=DESCRIPTION simple data segment rlimit test #=EXRESULT PASS profile rlimit { set rlimit data <= 4095KB, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_08.sd0000644000175000017500000000020113502024172022332 0ustar jjjj# #=DESCRIPTION simple max open file (same as ofile) rlimit test #=EXRESULT PASS profile rlimit { set rlimit nofile <= 256, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/ok_rlimit_11.sd0000644000175000017500000000014613502024172022334 0ustar jjjj# #=DESCRIPTION simple nproc rlimit test #=EXRESULT PASS profile rlimit { set rlimit nproc <= 1, } apparmor-2.13.3/parser/tst/simple_tests/rlimits/bad_rlimit_01.sd0000644000175000017500000000024513502024172022450 0ustar jjjj# #=DESCRIPTION realtime time rlimit test with ambiguous unit 'm' which could mean 'ms' or 'minutes' #=EXRESULT FAIL profile rlimit { set rlimit rttime <= 60m, } apparmor-2.13.3/parser/tst/simple_tests/abi/0000755000175000017500000000000013502024172016561 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/abi/ok_4.sd0000644000175000017500000000020013502024172017735 0ustar jjjj# #=DESCRIPTION abi testing - abi abs path in quotes with space #=EXRESULT PASS # abi "/abi/4.19 ubuntu", /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_21.sd0000644000175000017500000000015513502024172020025 0ustar jjjj# #=DESCRIPTION abi testing - abi path in profile #=EXRESULT PASS # /does/not/exist { abi "abi/4.19", } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_5.sd0000644000175000017500000000016013502024172017743 0ustar jjjj# #=DESCRIPTION abi testing - abi relative path no quotes #=EXRESULT PASS # abi abi/4.19, /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_11.sd0000644000175000017500000000020413502024172020017 0ustar jjjj# #=DESCRIPTION abi testing - abi path quotes in <> with spaces #=EXRESULT PASS #=DISABLED abi <"abi/4.19" >, /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/bad_1.sd0000644000175000017500000000016613502024172020062 0ustar jjjj# #=DESCRIPTION abi testing - abi relative path in quotes #=EXRESULT FAIL #=TODO abi "abi/4.19, /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_3.sd0000644000175000017500000000015613502024172017746 0ustar jjjj# #=DESCRIPTION abi testing - abi abs path in quotes #=EXRESULT PASS # abi "/abi/4.19", /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_16.sd0000644000175000017500000000017413502024172020032 0ustar jjjj# #=DESCRIPTION abi testing - abi path with space between path and , #=EXRESULT PASS # abi abi/4.19 , /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_10.sd0000644000175000017500000000031213502024172020016 0ustar jjjj# #=DESCRIPTION abi testing - abi path quotes in <> with spaces #=EXRESULT PASS #=TODO #=DISABLED - results in "superfluous TODO", but fails after removing TODO abi < "abi/4.19">, /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/bad_5.sd0000644000175000017500000000017113502024172020062 0ustar jjjj# #=DESCRIPTION abi testing - abi relative path no quotes missing , #=EXRESULT FAIL # abi abi/4.19 /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/bad_6.sd0000644000175000017500000000014313502024172020062 0ustar jjjj# #=DESCRIPTION abi testing - abi path #=EXRESULT FAIL #=TODO abi with spaces #=EXRESULT PASS #=TODO #=DISABLED - results in "superfluous TODO", but fails after removing TODO abi < "abi/4.19" >, /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_7.sd0000644000175000017500000000014713502024172017752 0ustar jjjj# #=DESCRIPTION abi testing - abi path spaces #=EXRESULT PASS # abi < abi/4.19>, /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/bad_4.sd0000644000175000017500000000017713502024172020067 0ustar jjjj# #=DESCRIPTION abi testing - abi abs path in quotes with space #=EXRESULT FAIL # abi "/abi/4.19 ubuntu, /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_15.sd0000644000175000017500000000017613502024172020033 0ustar jjjj# #=DESCRIPTION abi testing - abi path with space between path and , #=EXRESULT PASS # abi "abi/4.19" , /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/bad_12.sd0000644000175000017500000000017413502024172020143 0ustar jjjj# #=DESCRIPTION abi testing - abi path quotes in <> with spaces #=EXRESULT FAIL # abi < "abi/4.19" >, /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_8.sd0000644000175000017500000000014713502024172017753 0ustar jjjj# #=DESCRIPTION abi testing - abi path spaces #=EXRESULT PASS # abi , /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_14.sd0000644000175000017500000000017613502024172020032 0ustar jjjj# #=DESCRIPTION abi testing - abi path with space between path and , #=EXRESULT PASS # abi , /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_20.sd0000644000175000017500000000015513502024172020024 0ustar jjjj# #=DESCRIPTION abi testing - abi path in profile #=EXRESULT PASS # /does/not/exist { abi , } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_6.sd0000644000175000017500000000013713502024172017750 0ustar jjjj# #=DESCRIPTION abi testing - abi path #=EXRESULT PASS # abi , /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_18.sd0000644000175000017500000000017413502024172020034 0ustar jjjj# #=DESCRIPTION abi testing - abi path no space between and and path #=EXRESULT PASS # abi"abi/4.19", /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_22.sd0000644000175000017500000000015313502024172020024 0ustar jjjj# #=DESCRIPTION abi testing - abi path in profile #=EXRESULT PASS # /does/not/exist { abi abi/4.19, } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_9.sd0000644000175000017500000000015013502024172017746 0ustar jjjj# #=DESCRIPTION abi testing - abi path spaces #=EXRESULT PASS # abi < abi/4.19 >, /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_13.sd0000644000175000017500000000020113502024172020016 0ustar jjjj# #=DESCRIPTION abi testing - abi path quotes in <> with spaces #=EXRESULT PASS # abi <"abi/4.19 ubuntu">, /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/bad_11.sd0000644000175000017500000000017313502024172020141 0ustar jjjj# #=DESCRIPTION abi testing - abi path quotes in <> with spaces #=EXRESULT FAIL # abi <"abi/4.19" >, /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/bad_2.sd0000644000175000017500000000017513502024172020063 0ustar jjjj# #=DESCRIPTION abi testing - abi relative path in quotes with spaces #=EXRESULT FAIL # abi abi/4.19", /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/bad_10.sd0000644000175000017500000000017313502024172020140 0ustar jjjj# #=DESCRIPTION abi testing - abi path quotes in <> with spaces #=EXRESULT FAIL # abi < "abi/4.19">, /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_2.sd0000644000175000017500000000020513502024172017740 0ustar jjjj# #=DESCRIPTION abi testing - abi relative path in quotes with spaces #=EXRESULT PASS # abi "abi/4.19 ubuntu", /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/bad_3.sd0000644000175000017500000000015513502024172020062 0ustar jjjj# #=DESCRIPTION abi testing - abi abs path in quotes #=EXRESULT FAIL # abi "/abi/4.19" /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_17.sd0000644000175000017500000000017413502024172020033 0ustar jjjj# #=DESCRIPTION abi testing - abi path no space between and and path #=EXRESULT PASS # abi, /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/abi/ok_1.sd0000644000175000017500000000016213502024172017741 0ustar jjjj# #=DESCRIPTION abi testing - abi relative path in quotes #=EXRESULT PASS # abi "abi/4.19", /does/not/exist { } apparmor-2.13.3/parser/tst/simple_tests/unix/0000755000175000017500000000000013502024172017011 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/unix/bad_attr_1.sd0000644000175000017500000000017413502024172021343 0ustar jjjj# #=DESCRIPTION simple unix getattr w/peer modifier #=EXRESULT FAIL profile a_profile { unix getattr peer=(addr=none), } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_create_1.sd0000644000175000017500000000021713502024172021632 0ustar jjjj# #=DESCRIPTION simple unix create w/peer acceptance test #=EXRESULT FAIL profile a_profile { unix create peer=(label=/usr/sbin/apache2), } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_shutdown_2.sd0000644000175000017500000000021413502024172022240 0ustar jjjj# #=DESCRIPTION simple unix shutdown acceptance test #=EXRESULT FAIL profile a_profile { unix (shutdown) peer=(label=@{profile_name}), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_opt_2.sd0000644000175000017500000000015313502024172021054 0ustar jjjj# #=DESCRIPTION simple unix getopt acceptance test #=EXRESULT PASS profile a_profile { unix (getopt), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_15.sd0000644000175000017500000000013013502024172021117 0ustar jjjj# #=DESCRIPTION simple unix msg test #=EXRESULT PASS profile a_profile { unix (r), } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_regex_03.sd0000644000175000017500000000020113502024172021554 0ustar jjjj# #=DESCRIPTION unix rule with a bad peer regex expansion #=EXRESULT FAIL # profile foo { unix send peer=(label=spla{t,r ), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_17.sd0000644000175000017500000000013013502024172021121 0ustar jjjj# #=DESCRIPTION simple unix msg test #=EXRESULT PASS profile a_profile { unix (w), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_attr_1.sd0000644000175000017500000000015313502024172021223 0ustar jjjj# #=DESCRIPTION simple unix getattr acceptance test #=EXRESULT PASS profile a_profile { unix getattr, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_12.sd0000644000175000017500000000021013502024172021437 0ustar jjjj# #=DESCRIPTION unix rule with peer regex expansion that needs escaping #=EXRESULT PASS # profile foo { unix peer=(label=splat\ ), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_16.sd0000644000175000017500000000021013502024172021443 0ustar jjjj# #=DESCRIPTION unix rule with peer regex expansion that needs escaping #=EXRESULT PASS # profile foo { unix peer=(label=splat\(), } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_opt_3.sd0000644000175000017500000000022113502024172021166 0ustar jjjj# #=DESCRIPTION simple unix setopt w/peer addr test #=EXRESULT FAIL profile a_profile { unix setopt peer=(addr=@/dbus-vfs-daemon/socket-*), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_19.sd0000644000175000017500000000013113502024172021124 0ustar jjjj# #=DESCRIPTION simple unix msg test #=EXRESULT PASS profile a_profile { unix (rw), } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_regex_02.sd0000644000175000017500000000015513502024172021563 0ustar jjjj# #=DESCRIPTION unix rule with a bad expansion #=EXRESULT FAIL # profile foo { unix bind addr=abcd]efg, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_09.sd0000644000175000017500000000021513502024172021452 0ustar jjjj# #=DESCRIPTION unix rule with regex expansion that is quoted with quote escaped #=EXRESULT PASS # profile foo { unix addr="@splat \"", } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_07.sd0000644000175000017500000000017413502024172021454 0ustar jjjj# #=DESCRIPTION unix rule with regex expansion that needs escaping #=EXRESULT PASS # profile foo { unix addr=@splat\), } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_attr_4.sd0000644000175000017500000000020113502024172021335 0ustar jjjj# #=DESCRIPTION simple unix setattr w/peer addr test #=EXRESULT FAIL profile a_profile { unix (setattr) peer=(addr=@spork), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_shutdown_2.sd0000644000175000017500000000015713502024172022131 0ustar jjjj# #=DESCRIPTION simple unix shutdown acceptance test #=EXRESULT PASS profile a_profile { unix (shutdown), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_8.sd0000644000175000017500000000014513502024172021047 0ustar jjjj# #=DESCRIPTION simple unix msg test #=EXRESULT PASS profile a_profile { unix (send) addr=@foo, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_6.sd0000644000175000017500000000015513502024172021046 0ustar jjjj# #=DESCRIPTION simple unix msg test #=EXRESULT PASS profile a_profile { unix (send, receive, connect), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_shutdown_3.sd0000644000175000017500000000022413502024172022125 0ustar jjjj# #=DESCRIPTION simple unix shutdown w/addr acceptance test #=EXRESULT PASS profile a_profile { unix shutdown addr=@HypotheticalServiceDaemon, } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_modifier_1.sd0000644000175000017500000000016513502024172022167 0ustar jjjj# #=DESCRIPTION unix entry with a bad modifier #=EXRESULT FAIL profile foo { unix send type=dgram modifier=foo, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_connect_2.sd0000644000175000017500000000015513502024172021705 0ustar jjjj# #=DESCRIPTION simple unix connect acceptance test #=EXRESULT PASS profile a_profile { unix (connect), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_embedded_0_2.sd0000644000175000017500000000015113502024172022220 0ustar jjjj# #=DESCRIPTION unix rule with embedded \x00 #=EXRESULT PASS # profile foo { unix addr=@foo\x00bar, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_shutdown_1.sd0000644000175000017500000000015513502024172022126 0ustar jjjj# #=DESCRIPTION simple unix shutdown acceptance test #=EXRESULT PASS profile a_profile { unix shutdown, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_opt_5.sd0000644000175000017500000000020413502024172021054 0ustar jjjj# #=DESCRIPTION simple unix getopt w/addr acceptance test #=EXRESULT PASS profile a_profile { unix getopt addr=@private/defer, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_7.sd0000644000175000017500000000014513502024172021046 0ustar jjjj# #=DESCRIPTION simple unix msg test #=EXRESULT PASS profile a_profile { unix (send) addr=none, } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_opt_4.sd0000644000175000017500000000020513502024172021171 0ustar jjjj# #=DESCRIPTION simple unix setopt w/peer label test #=EXRESULT FAIL profile a_profile { unix (setopt) peer=(label=unconfined), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_attr_4.sd0000644000175000017500000000015513502024172021230 0ustar jjjj# #=DESCRIPTION simple unix setattr acceptance test #=EXRESULT PASS profile a_profile { unix (setattr), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_18.sd0000644000175000017500000000020413502024172021450 0ustar jjjj# #=DESCRIPTION unix rule with peer regex expansion that is quoted #=EXRESULT PASS # profile foo { unix peer=(label="splat "), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_11.sd0000644000175000017500000000012013502024172021112 0ustar jjjj# #=DESCRIPTION simple unix rule #=EXRESULT PASS profile a_profile { unix, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_15.sd0000644000175000017500000000021013502024172021442 0ustar jjjj# #=DESCRIPTION unix rule with peer regex expansion that needs escaping #=EXRESULT PASS # profile foo { unix peer=(label=splat\,), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_9.sd0000644000175000017500000000015413502024172021050 0ustar jjjj# #=DESCRIPTION simple unix msg test #=EXRESULT PASS profile a_profile { unix (send) peer=(addr=@foo), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_18.sd0000644000175000017500000000012713502024172021130 0ustar jjjj# #=DESCRIPTION simple unix msg test #=EXRESULT PASS profile a_profile { unix rw, } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_regex_01.sd0000644000175000017500000000021713502024172021561 0ustar jjjj# #=DESCRIPTION unix rule with a bad addr regex expansion #=EXRESULT FAIL # profile foo { unix send addr=@foo{one,two peer=(label=splat), } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_attr_2.sd0000644000175000017500000000020513502024172021337 0ustar jjjj# #=DESCRIPTION simple unix getattr acceptance test #=EXRESULT FAIL profile a_profile { unix (getattr) peer=(label=unconfined), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_attr_5.sd0000644000175000017500000000017413502024172021232 0ustar jjjj# #=DESCRIPTION simple unix getattr w/addr acceptance test #=EXRESULT PASS profile a_profile { unix getattr addr=none, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_1.sd0000644000175000017500000000013413502024172021036 0ustar jjjj# #=DESCRIPTION simple unix send test #=EXRESULT PASS profile a_profile { unix (send), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_create_2.sd0000644000175000017500000000015313502024172021515 0ustar jjjj# #=DESCRIPTION simple unix create acceptance test #=EXRESULT PASS profile a_profile { unix (create), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_01.sd0000644000175000017500000000017413502024172021446 0ustar jjjj# #=DESCRIPTION unix rule with regex expansion that needs escaping #=EXRESULT PASS # profile foo { unix addr=@splat\ , } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_12.sd0000644000175000017500000000013213502024172021116 0ustar jjjj# #=DESCRIPTION simple unix send test #=EXRESULT PASS profile a_profile { unix send, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_create_3.sd0000644000175000017500000000017213502024172021517 0ustar jjjj# #=DESCRIPTION simple unix create w/addr acceptance test #=EXRESULT PASS profile a_profile { unix create addr=none, } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_opt_1.sd0000644000175000017500000000017313502024172021172 0ustar jjjj# #=DESCRIPTION simple unix getopt w/peer addr test #=EXRESULT FAIL profile a_profile { unix getopt peer=(addr=none), } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_bind_2.sd0000644000175000017500000000017713502024172021311 0ustar jjjj# #=DESCRIPTION unix bind with non-bind interface modifier #=EXRESULT FAIL # profile foo { unix bind label=foo addr=@bar, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_connect_1.sd0000644000175000017500000000015313502024172021702 0ustar jjjj# #=DESCRIPTION simple unix connect acceptance test #=EXRESULT PASS profile a_profile { unix connect, } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_bind_1.sd0000644000175000017500000000017213502024172021303 0ustar jjjj# #=DESCRIPTION unix bind with non-bind member modifier #=EXRESULT FAIL # profile foo { unix bind peer=(addr=@foo ), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_06.sd0000644000175000017500000000017413502024172021453 0ustar jjjj# #=DESCRIPTION unix rule with regex expansion that needs escaping #=EXRESULT PASS # profile foo { unix addr=@splat\(, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_opt_1.sd0000644000175000017500000000015113502024172021051 0ustar jjjj# #=DESCRIPTION simple unix getopt acceptance test #=EXRESULT PASS profile a_profile { unix getopt, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_opt_3.sd0000644000175000017500000000015113502024172021053 0ustar jjjj# #=DESCRIPTION simple unix setopt acceptance test #=EXRESULT PASS profile a_profile { unix setopt, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_embedded_0_1.sd0000644000175000017500000000015113502024172022217 0ustar jjjj# #=DESCRIPTION unix rule with embedded \000 #=EXRESULT PASS # profile foo { unix addr=@foo\000bar, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_4.sd0000644000175000017500000000013313502024172021040 0ustar jjjj# #=DESCRIPTION simple unix msg test #=EXRESULT PASS profile a_profile { unix (send), } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_listen_2.sd0000644000175000017500000000017413502024172021670 0ustar jjjj# #=DESCRIPTION simple unix listen w/peer test #=EXRESULT FAIL profile a_profile { unix (listen) peer=(addr=@unknown), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_bind_3.sd0000644000175000017500000000014713502024172021172 0ustar jjjj# #=DESCRIPTION simple unix bind acceptance test #=EXRESULT PASS profile a_profile { unix (bind), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_accept_1.sd0000644000175000017500000000015113502024172021506 0ustar jjjj# #=DESCRIPTION simple unix accept acceptance test #=EXRESULT PASS profile a_profile { unix accept, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_listen_2.sd0000644000175000017500000000015313502024172021550 0ustar jjjj# #=DESCRIPTION simple unix listen acceptance test #=EXRESULT PASS profile a_profile { unix (listen), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_16.sd0000644000175000017500000000012613502024172021125 0ustar jjjj# #=DESCRIPTION simple unix msg test #=EXRESULT PASS profile a_profile { unix w, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_embedded_0_3.sd0000644000175000017500000000015113502024172022221 0ustar jjjj# #=DESCRIPTION unix rule with embedded \d00 #=EXRESULT PASS # profile foo { unix addr=@foo\d00bar, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_13.sd0000644000175000017500000000021013502024172021440 0ustar jjjj# #=DESCRIPTION unix rule with peer regex expansion that needs escaping #=EXRESULT PASS # profile foo { unix peer=(label=splat\"), } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_modifier_3.sd0000644000175000017500000000017113502024172022166 0ustar jjjj# #=DESCRIPTION unix entry with a bad 'in' keyword #=EXRESULT FAIL profile foo { unix send type in (dgram, stream), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_5.sd0000644000175000017500000000014413502024172021043 0ustar jjjj# #=DESCRIPTION simple unix msg test #=EXRESULT PASS profile a_profile { unix (send, receive), } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_modifier_2.sd0000644000175000017500000000017113502024172022165 0ustar jjjj# #=DESCRIPTION unix entry with a repeated modifier #=EXRESULT FAIL profile foo { unix send type=stream type=dgram, } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_peer_1.sd0000644000175000017500000000026013502024172021320 0ustar jjjj# #=Description unix rule with bad 'peer' #=EXRESULT FAIL # # path address must be none for anonymous or start with @ for abstract profile foo { unix send peer(addr=wat), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_11.sd0000644000175000017500000000021013502024172021436 0ustar jjjj# #=DESCRIPTION unix rule with peer regex expansion that needs escaping #=EXRESULT PASS # profile foo { unix peer=(label=splat\ ), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_accept_2.sd0000644000175000017500000000015313502024172021511 0ustar jjjj# #=DESCRIPTION simple unix accept acceptance test #=EXRESULT PASS profile a_profile { unix (accept), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_attr_3.sd0000644000175000017500000000015313502024172021225 0ustar jjjj# #=DESCRIPTION simple unix setattr acceptance test #=EXRESULT PASS profile a_profile { unix setattr, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_opt_6.sd0000644000175000017500000000017213502024172021061 0ustar jjjj# #=DESCRIPTION simple unix setopt w/addr acceptance test #=EXRESULT PASS profile a_profile { unix setopt addr=none, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_2.sd0000644000175000017500000000013613502024172021041 0ustar jjjj# #=DESCRIPTION simple unix msg test #=EXRESULT PASS profile a_profile { unix (receive), } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_modifier_4.sd0000644000175000017500000000017513502024172022173 0ustar jjjj# #=DESCRIPTION unix entry with a bad multivalue modifier #=EXRESULT FAIL profile foo { unix send type=(stream, dgram), } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_outside_1.sd0000644000175000017500000000012613502024172022042 0ustar jjjj# #=DESCRIPTION unix accept rule outside of a profile #=EXRESULT FAIL unix accept, apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_17.sd0000644000175000017500000000021013502024172021444 0ustar jjjj# #=DESCRIPTION unix rule with peer regex expansion that needs escaping #=EXRESULT PASS # profile foo { unix peer=(label=splat\)), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_create_1.sd0000644000175000017500000000015113502024172021512 0ustar jjjj# #=DESCRIPTION simple unix create acceptance test #=EXRESULT PASS profile a_profile { unix create, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_08.sd0000644000175000017500000000017013502024172021451 0ustar jjjj# #=DESCRIPTION unix rule with regex expansion that is quoted #=EXRESULT PASS # profile foo { unix addr="@splat ", } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_attr_2.sd0000644000175000017500000000015513502024172021226 0ustar jjjj# #=DESCRIPTION simple unix getattr acceptance test #=EXRESULT PASS profile a_profile { unix (getattr), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_opt_4.sd0000644000175000017500000000015313502024172021056 0ustar jjjj# #=DESCRIPTION simple unix setopt acceptance test #=EXRESULT PASS profile a_profile { unix (setopt), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_04.sd0000644000175000017500000000017413502024172021451 0ustar jjjj# #=DESCRIPTION unix rule with regex expansion that needs escaping #=EXRESULT PASS # profile foo { unix addr=@splat\!, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_bind_1.sd0000644000175000017500000000017313502024172021167 0ustar jjjj# #=DESCRIPTION simple unix implicit bind acceptance test #=EXRESULT PASS profile a_profile { unix addr=@SomeService, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_3.sd0000644000175000017500000000013613502024172021042 0ustar jjjj# #=DESCRIPTION simple unix msg test #=EXRESULT PASS profile a_profile { unix (connect), } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_regex_04.sd0000644000175000017500000000023513502024172021564 0ustar jjjj# #=DESCRIPTION unix rule with a bad path address regex expansion #=EXRESULT FAIL # profile foo { unix send addr=/some/random/{path peer=(label=splat), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_listen_1.sd0000644000175000017500000000015113502024172021545 0ustar jjjj# #=DESCRIPTION simple unix listen acceptance test #=EXRESULT PASS profile a_profile { unix listen, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_03.sd0000644000175000017500000000017413502024172021450 0ustar jjjj# #=DESCRIPTION unix rule with regex expansion that needs escaping #=EXRESULT PASS # profile foo { unix addr=@splat\", } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_14.sd0000644000175000017500000000012613502024172021123 0ustar jjjj# #=DESCRIPTION simple unix msg test #=EXRESULT PASS profile a_profile { unix r, } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_attr_3.sd0000644000175000017500000000017313502024172021344 0ustar jjjj# #=DESCRIPTION simple unix setattr w/peer test #=EXRESULT FAIL profile a_profile { unix setattr peer=(label=orange), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_bind_2.sd0000644000175000017500000000014513502024172021167 0ustar jjjj# #=DESCRIPTION simple unix bind acceptance test #=EXRESULT PASS profile a_profile { unix bind, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_listen_3.sd0000644000175000017500000000017413502024172021554 0ustar jjjj# #=DESCRIPTION simple unix listen w/addr acceptance test #=EXRESULT PASS profile a_profile { unix listen addr=@foo**, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_05.sd0000644000175000017500000000017413502024172021452 0ustar jjjj# #=DESCRIPTION unix rule with regex expansion that needs escaping #=EXRESULT PASS # profile foo { unix addr=@splat\,, } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_14.sd0000644000175000017500000000021013502024172021441 0ustar jjjj# #=DESCRIPTION unix rule with peer regex expansion that needs escaping #=EXRESULT PASS # profile foo { unix peer=(label=splat\!), } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_create_2.sd0000644000175000017500000000020113502024172021624 0ustar jjjj# #=DESCRIPTION simple unix create acceptance test #=EXRESULT FAIL profile a_profile { unix (create) peer=(addr=@somesuch), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_19.sd0000644000175000017500000000023113502024172021451 0ustar jjjj# #=DESCRIPTION unix rule with peer regex expansion that is quoted with quote escaped #=EXRESULT PASS # profile foo { unix peer=(label="splat \""), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_13.sd0000644000175000017500000000013413502024172021121 0ustar jjjj# #=DESCRIPTION simple unix msg test #=EXRESULT PASS profile a_profile { unix receive, } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_shutdown_1.sd0000644000175000017500000000017213502024172022242 0ustar jjjj# #=DESCRIPTION simple unix shutdown w/peer test #=EXRESULT FAIL profile a_profile { unix shutdown peer=(addr=none), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_attr_6.sd0000644000175000017500000000017413502024172021233 0ustar jjjj# #=DESCRIPTION simple unix setattr w/addr acceptance test #=EXRESULT PASS profile a_profile { unix setattr addr=none, } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_opt_2.sd0000644000175000017500000000020413502024172021166 0ustar jjjj# #=DESCRIPTION simple unix getopt w/peer label test #=EXRESULT FAIL profile a_profile { unix (getopt) peer=(label=strongbad), } apparmor-2.13.3/parser/tst/simple_tests/unix/bad_listen_1.sd0000644000175000017500000000020613502024172021663 0ustar jjjj# #=DESCRIPTION simple unix listen w/peer test #=EXRESULT FAIL profile a_profile { unix listen peer=(label=you_cannot_label_me), } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_regex_02.sd0000644000175000017500000000017413502024172021447 0ustar jjjj# #=DESCRIPTION unix rule with regex expansion that needs escaping #=EXRESULT PASS # profile foo { unix addr=@splat\ , } apparmor-2.13.3/parser/tst/simple_tests/unix/ok_msg_10.sd0000644000175000017500000000015413502024172021120 0ustar jjjj# #=DESCRIPTION simple unix msg test #=EXRESULT PASS profile a_profile { unix (send) peer=(label=foo), } apparmor-2.13.3/parser/tst/simple_tests/change_profile/0000755000175000017500000000000013502024172020773 5ustar jjjjapparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_ok_5.sd0000644000175000017500000000036413502024172023513 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { audit deny change_profile /onexec -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_re_ok_7.sd0000644000175000017500000000177313502024172024047 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec with just re, namespace #=EXRESULT PASS # /usr/bin/foo { deny change_profile /onexec -> :ab:*, } /usr/bin/foo2 { deny change_profile /onexec -> :ab:**, } /usr/bin/foo3 { deny change_profile /onexec -> :ab:?, } /usr/bin/foo4 { deny change_profile /onexec -> :ab:[ab], } /usr/bin/foo5 { deny change_profile /onexec -> :ab:[^ab], } /usr/bin/foo6 { deny change_profile /onexec -> :*:ab, } /usr/bin/foo7 { deny change_profile /onexec -> :**:ab, } /usr/bin/foo8 { deny change_profile /onexec -> :?:ab, } /usr/bin/foo9 { deny change_profile /onexec -> :[ab]:ab, } /usr/bin/foo10 { deny change_profile /onexec -> :[^ab]:ab, } /usr/bin/foo11 { deny change_profile /onexec -> :*:*, } /usr/bin/foo12 { deny change_profile /onexec -> :**:**, } /usr/bin/foo13 { deny change_profile /onexec -> :?:?, } /usr/bin/foo14 { deny change_profile /onexec -> :[ab]:[ab], } /usr/bin/foo15 { deny change_profile /onexec -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_re_bad_6.sd0000644000175000017500000000021513502024172024325 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit owner change_profile /onexec -> *//ab, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_re_bad_7.sd0000644000175000017500000000022313502024172024471 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit deny owner change_profile /onexec -> :ab:*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_bad_5.sd0000644000175000017500000000035313502024172024516 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { audit deny owner change_profile @{var} -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_re_bad_2.sd0000644000175000017500000000024013502024172025030 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit owner change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_bad_5.sd0000644000175000017500000000034513502024172024356 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { deny owner change_profile @{var} -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allow_re_ok_3.sd0000644000175000017500000000207413502024172024045 0ustar jjjj# #=DESCRIPTION allow change_profile with name space #=EXRESULT PASS # /usr/bin/foo { allow change_profile -> :foo:/bin/foo, } /usr/bin/foo2 { allow change_profile -> :foo:/bin/fo*, } /usr/bin/foo3 { allow change_profile -> :foo:/bin/fo**, } /usr/bin/foo4 { allow change_profile -> :foo:/bin/fo?, } /usr/bin/foo5 { allow change_profile -> :foo:/bin/fo[ab], } /usr/bin/foo6 { allow change_profile -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { allow change_profile -> :fo*:/bin/foo, } /usr/bin/foo8 { allow change_profile -> :fo**:/bin/foo, } /usr/bin/foo9 { allow change_profile -> :fo?:/bin/foo, } /usr/bin/foo10 { allow change_profile -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { allow change_profile -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { allow change_profile -> :fo*:/bin/fo*, } /usr/bin/foo13 { allow change_profile -> :fo**:/bin/fo**, } /usr/bin/foo14 { allow change_profile -> :fo?:/bin/fo?, } /usr/bin/foo15 { allow change_profile -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { allow change_profile -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_ok_4.sd0000644000175000017500000000025013502024172022454 0ustar jjjj# #=DESCRIPTION audit change_profile with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { audit change_profile -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_bad_2.sd0000644000175000017500000000023113502024172023775 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit deny owner change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_aao_bad_8.sd0000644000175000017500000000025013502024172024512 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit allow owner change_profile @{var} -> ":foo:/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_re_bad_3.sd0000644000175000017500000000021613502024172024162 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { owner change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_re_bad_8.sd0000644000175000017500000000021513502024172025025 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # /usr/bin/foo5 { deny audit change_profile @{var} -> "/bin/*", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_re_ok_3.sd0000644000175000017500000000213613502024172023532 0ustar jjjj# #=DESCRIPTION change_profile /onexec with name space #=EXRESULT PASS # /usr/bin/foo { change_profile /onexec -> :foo:/bin/foo, } /usr/bin/foo2 { change_profile /onexec -> :foo:/bin/fo*, } /usr/bin/foo3 { change_profile /onexec -> :foo:/bin/fo**, } /usr/bin/foo4 { change_profile /onexec -> :foo:/bin/fo?, } /usr/bin/foo5 { change_profile /onexec -> :foo:/bin/fo[ab], } /usr/bin/foo6 { change_profile /onexec -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { change_profile /onexec -> :fo*:/bin/foo, } /usr/bin/foo8 { change_profile /onexec -> :fo**:/bin/foo, } /usr/bin/foo9 { change_profile /onexec -> :fo?:/bin/foo, } /usr/bin/foo10 { change_profile /onexec -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { change_profile /onexec -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { change_profile /onexec -> :fo*:/bin/fo*, } /usr/bin/foo13 { change_profile /onexec -> :fo**:/bin/fo**, } /usr/bin/foo14 { change_profile /onexec -> :fo?:/bin/fo?, } /usr/bin/foo15 { change_profile /onexec -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { change_profile /onexec -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_bad_2.sd0000644000175000017500000000022413502024172023633 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit owner change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allow_re_ok_8.sd0000644000175000017500000000122613502024172024050 0ustar jjjj# #=DESCRIPTION allow change_profile re with quotes #=EXRESULT PASS # /usr/bin/foo5 { allow change_profile -> "/bin/*", } /usr/bin/foo6 { allow change_profile -> "/bin/**", } /usr/bin/foo7 { allow change_profile -> "/bin/[ab]", } /usr/bin/foo8 { allow change_profile -> "/bin/[^ab]", } /usr/bin/foo10 { allow change_profile -> "/bin/?ab", } /usr/bin/foo11 { allow change_profile -> "/bin/ *", } /usr/bin/foo12 { allow change_profile -> "/bin/ **", } /usr/bin/foo13 { allow change_profile -> "/bin/ [ab]", } /usr/bin/foo14 { allow change_profile -> "/bin/ [^ab]", } /usr/bin/foo15 { allow change_profile -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_ok_6.sd0000644000175000017500000000033513502024172023512 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec with quotes #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile /onexec -> "/bin/foo", } /usr/bin/foo2 { audit deny change_profile /onexec -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_bad_2.sd0000644000175000017500000000024013502024172024342 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit owner change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_bad_4.sd0000644000175000017500000000025313502024172023642 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" /usr/bin/foo { deny owner change_profile /onexec -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_ok_3.sd0000644000175000017500000000024713502024172024222 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} with name space #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit deny change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_bad_7.sd0000644000175000017500000000024113502024172024353 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny owner change_profile @{var} -> "/bin/foo//bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_bare_bad_1.sd0000644000175000017500000000021013502024172024762 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit deny owner change_profile /onexec, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_re_ok_7.sd0000644000175000017500000000157313502024172023161 0ustar jjjj# #=DESCRIPTION deny change_profile with just re, namespace #=EXRESULT PASS # /usr/bin/foo { deny change_profile -> :ab:*, } /usr/bin/foo2 { deny change_profile -> :ab:**, } /usr/bin/foo3 { deny change_profile -> :ab:?, } /usr/bin/foo4 { deny change_profile -> :ab:[ab], } /usr/bin/foo5 { deny change_profile -> :ab:[^ab], } /usr/bin/foo6 { deny change_profile -> :*:ab, } /usr/bin/foo7 { deny change_profile -> :**:ab, } /usr/bin/foo8 { deny change_profile -> :?:ab, } /usr/bin/foo9 { deny change_profile -> :[ab]:ab, } /usr/bin/foo10 { deny change_profile -> :[^ab]:ab, } /usr/bin/foo11 { deny change_profile -> :*:*, } /usr/bin/foo12 { deny change_profile -> :**:**, } /usr/bin/foo13 { deny change_profile -> :?:?, } /usr/bin/foo14 { deny change_profile -> :[ab]:[ab], } /usr/bin/foo15 { deny change_profile -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_aao_bad_2.sd0000644000175000017500000000024613502024172024511 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit allow owner change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_ok_2.sd0000644000175000017500000000020513502024172022616 0ustar jjjj# #=DESCRIPTION audit deny change_profile to a hat #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_ok_5.sd0000644000175000017500000000033213502024172022456 0ustar jjjj# #=DESCRIPTION audit change_profile with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { audit change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ok_4.sd0000644000175000017500000000023413502024172022156 0ustar jjjj# #=DESCRIPTION change_profile with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { change_profile -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_bad_1.sd0000644000175000017500000000023313502024172024343 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit owner change_profile @{var} -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_ok_4.sd0000644000175000017500000000026613502024172023352 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { deny change_profile /onexec -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_ok_4.sd0000644000175000017500000000031513502024172024217 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { audit deny change_profile @{var} -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_bad_5.sd0000644000175000017500000000032413502024172023476 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" /usr/bin/foo { owner change_profile /onexec -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aao_bad_2.sd0000644000175000017500000000023213502024172023773 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit allow owner change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allow_re_ok_4.sd0000644000175000017500000000152113502024172024042 0ustar jjjj# #=DESCRIPTION allow change_profile with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { allow change_profile -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { allow change_profile -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { allow change_profile -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { allow change_profile -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { allow change_profile -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { allow change_profile -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { allow change_profile -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { allow change_profile -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { allow change_profile -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { allow change_profile -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { allow change_profile -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_bad_2.sd0000644000175000017500000000023713502024172024353 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny owner change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_bad_7.sd0000644000175000017500000000023413502024172024211 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { owner change_profile @{var} -> "/bin/foo//bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ok_6.sd0000644000175000017500000000027413502024172023050 0ustar jjjj# #=DESCRIPTION change_profile /onexec with quotes #=EXRESULT PASS # /usr/bin/foo { change_profile /onexec -> "/bin/foo", } /usr/bin/foo2 { change_profile /onexec -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_allow_re_ok_8.sd0000644000175000017500000000136113502024172025445 0ustar jjjj# #=DESCRIPTION allow change_profile @{var} re with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo5 { allow change_profile @{var} -> "/bin/*", } /usr/bin/foo6 { allow change_profile @{var} -> "/bin/**", } /usr/bin/foo7 { allow change_profile @{var} -> "/bin/[ab]", } /usr/bin/foo8 { allow change_profile @{var} -> "/bin/[^ab]", } /usr/bin/foo10 { allow change_profile @{var} -> "/bin/?ab", } /usr/bin/foo11 { allow change_profile @{var} -> "/bin/ *", } /usr/bin/foo12 { allow change_profile @{var} -> "/bin/ **", } /usr/bin/foo13 { allow change_profile @{var} -> "/bin/ [ab]", } /usr/bin/foo14 { allow change_profile @{var} -> "/bin/ [^ab]", } /usr/bin/foo15 { allow change_profile @{var} -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aao_bad_4.sd0000644000175000017500000000026213502024172024000 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" /usr/bin/foo { audit allow owner change_profile /onexec -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_re_ok_4.sd0000644000175000017500000000155213502024172024245 0ustar jjjj# #=DESCRIPTION change_profile @{var} with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" @{var}=/test /usr/bin/foo { change_profile @{var} -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { change_profile @{var} -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { change_profile @{var} -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { change_profile @{var} -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { change_profile @{var} -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { change_profile @{var} -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { change_profile @{var} -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { change_profile @{var} -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { change_profile @{var} -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { change_profile @{var} -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { change_profile @{var} -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allow_ok_3.sd0000644000175000017500000000020213502024172023346 0ustar jjjj# #=DESCRIPTION allow change_profile with name space #=EXRESULT PASS # /usr/bin/foo { allow change_profile -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_re_ok_2.sd0000644000175000017500000000212513502024172024240 0ustar jjjj# #=DESCRIPTION change_profile @{var} to a hat #=EXRESULT PASS # @{var}=/test /usr/bin/foo { change_profile @{var} -> /bin/foo//bar, } /usr/bin/foo2 { change_profile @{var} -> /bin/foo//ba*, } /usr/bin/foo3 { change_profile @{var} -> /bin/foo//ba**, } /usr/bin/foo4 { change_profile @{var} -> /bin/foo//ba?, } /usr/bin/foo5 { change_profile @{var} -> /bin/foo//ba[ab], } /usr/bin/foo6 { change_profile @{var} -> /bin/foo//ba[^ab], } /usr/bin/foo7 { change_profile @{var} -> /bin/fo*//bar, } /usr/bin/foo8 { change_profile @{var} -> /bin/fo**//bar, } /usr/bin/foo9 { change_profile @{var} -> /bin/fo?//bar, } /usr/bin/foo10 { change_profile @{var} -> /bin/fo[ab]//bar, } /usr/bin/foo11 { change_profile @{var} -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { change_profile @{var} -> /bin/fo*//ba*, } /usr/bin/foo13 { change_profile @{var} -> /bin/fo**//ba**, } /usr/bin/foo14 { change_profile @{var} -> /bin/fo?//ba?, } /usr/bin/foo15 { change_profile @{var} -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { change_profile @{var} -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_ok_3.sd0000644000175000017500000000023513502024172024053 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} with name space #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_re_bad_2.sd0000644000175000017500000000022313502024172024323 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { deny owner change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/unsafe_ok_1.sd0000644000175000017500000000020313502024172023510 0ustar jjjj# #=DESCRIPTION change_profile w/ unsafe modifier #=EXRESULT PASS # /usr/bin/foo { change_profile unsafe /usr/bin/bar -> baz, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_re_ok_7.sd0000644000175000017500000000213313502024172024177 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec with just re, namespace #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile /onexec -> :ab:*, } /usr/bin/foo2 { audit deny change_profile /onexec -> :ab:**, } /usr/bin/foo3 { audit deny change_profile /onexec -> :ab:?, } /usr/bin/foo4 { audit deny change_profile /onexec -> :ab:[ab], } /usr/bin/foo5 { audit deny change_profile /onexec -> :ab:[^ab], } /usr/bin/foo6 { audit deny change_profile /onexec -> :*:ab, } /usr/bin/foo7 { audit deny change_profile /onexec -> :**:ab, } /usr/bin/foo8 { audit deny change_profile /onexec -> :?:ab, } /usr/bin/foo9 { audit deny change_profile /onexec -> :[ab]:ab, } /usr/bin/foo10 { audit deny change_profile /onexec -> :[^ab]:ab, } /usr/bin/foo11 { audit deny change_profile /onexec -> :*:*, } /usr/bin/foo12 { audit deny change_profile /onexec -> :**:**, } /usr/bin/foo13 { audit deny change_profile /onexec -> :?:?, } /usr/bin/foo14 { audit deny change_profile /onexec -> :[ab]:[ab], } /usr/bin/foo15 { audit deny change_profile /onexec -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_ok_2.sd0000644000175000017500000000022613502024172024052 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} to a hat #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_bad_8.sd0000644000175000017500000000022013502024172023474 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { owner change_profile /onexec -> ":foo:/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_bare_ok_1.sd0000644000175000017500000000020613502024172025204 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit deny change_profile @{var}, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aao_re_bad_8.sd0000644000175000017500000000022713502024172024473 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo5 { audit allow owner change_profile /onexec -> "/bin/*", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/safe_ok_1.sd0000644000175000017500000000017713502024172023157 0ustar jjjj# #=DESCRIPTION change_profile w/ safe modifier #=EXRESULT PASS # /usr/bin/foo { change_profile safe /usr/bin/bar -> baz, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_re_ok_6.sd0000644000175000017500000000201013502024172024024 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec with just res, child profile #=EXRESULT PASS # /usr/bin/foo { audit change_profile /onexec -> *//ab, } /usr/bin/foo2 { audit change_profile /onexec -> **//ab, } /usr/bin/foo3 { audit change_profile /onexec -> ?//ab, } /usr/bin/foo4 { audit change_profile /onexec -> [ab]//ab, } /usr/bin/foo5 { audit change_profile /onexec -> [^ab]//ab, } /usr/bin/foo6 { audit change_profile /onexec -> ab//*, } /usr/bin/foo7 { audit change_profile /onexec -> ab//**, } /usr/bin/foo8 { audit change_profile /onexec -> ab//?, } /usr/bin/foo9 { audit change_profile /onexec -> ab//[ab], } /usr/bin/foo10 { audit change_profile /onexec -> ab//[^ab], } /usr/bin/foo11 { audit change_profile /onexec -> *//*, } /usr/bin/foo12 { audit change_profile /onexec -> **//*, } /usr/bin/foo13 { audit change_profile /onexec -> ?//*, } /usr/bin/foo14 { audit change_profile /onexec -> [ab]//*, } /usr/bin/foo15 { audit change_profile /onexec -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aa_ok_5.sd0000644000175000017500000000036613502024172023512 0ustar jjjj# #=DESCRIPTION audit allow change_profile /onexec with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { audit allow change_profile /onexec -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_re_bad_1.sd0000644000175000017500000000023113502024172025027 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit owner change_profile @{var} -> /bin/*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_re_bad_1.sd0000644000175000017500000000021413502024172024322 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { deny owner change_profile /onexec -> /bin/*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aao_bad_3.sd0000644000175000017500000000023213502024172023774 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit allow owner change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_re_ok_3.sd0000644000175000017500000000242513502024172024710 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} with name space #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit deny change_profile @{var} -> :foo:/bin/foo, } /usr/bin/foo2 { audit deny change_profile @{var} -> :foo:/bin/fo*, } /usr/bin/foo3 { audit deny change_profile @{var} -> :foo:/bin/fo**, } /usr/bin/foo4 { audit deny change_profile @{var} -> :foo:/bin/fo?, } /usr/bin/foo5 { audit deny change_profile @{var} -> :foo:/bin/fo[ab], } /usr/bin/foo6 { audit deny change_profile @{var} -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { audit deny change_profile @{var} -> :fo*:/bin/foo, } /usr/bin/foo8 { audit deny change_profile @{var} -> :fo**:/bin/foo, } /usr/bin/foo9 { audit deny change_profile @{var} -> :fo?:/bin/foo, } /usr/bin/foo10 { audit deny change_profile @{var} -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { audit deny change_profile @{var} -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { audit deny change_profile @{var} -> :fo*:/bin/fo*, } /usr/bin/foo13 { audit deny change_profile @{var} -> :fo**:/bin/fo**, } /usr/bin/foo14 { audit deny change_profile @{var} -> :fo?:/bin/fo?, } /usr/bin/foo15 { audit deny change_profile @{var} -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { audit deny change_profile @{var} -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_re_ok_6.sd0000644000175000017500000000164513502024172024252 0ustar jjjj# #=DESCRIPTION change_profile @{var} with just res, child profile #=EXRESULT PASS # @{var}=/test /usr/bin/foo { change_profile @{var} -> *//ab, } /usr/bin/foo2 { change_profile @{var} -> **//ab, } /usr/bin/foo3 { change_profile @{var} -> ?//ab, } /usr/bin/foo4 { change_profile @{var} -> [ab]//ab, } /usr/bin/foo5 { change_profile @{var} -> [^ab]//ab, } /usr/bin/foo6 { change_profile @{var} -> ab//*, } /usr/bin/foo7 { change_profile @{var} -> ab//**, } /usr/bin/foo8 { change_profile @{var} -> ab//?, } /usr/bin/foo9 { change_profile @{var} -> ab//[ab], } /usr/bin/foo10 { change_profile @{var} -> ab//[^ab], } /usr/bin/foo11 { change_profile @{var} -> *//*, } /usr/bin/foo12 { change_profile @{var} -> **//*, } /usr/bin/foo13 { change_profile @{var} -> ?//*, } /usr/bin/foo14 { change_profile @{var} -> [ab]//*, } /usr/bin/foo15 { change_profile @{var} -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_bare_bad_1.sd0000644000175000017500000000017513502024172024467 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { owner change_profile /onexec, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allow_ok_7.sd0000644000175000017500000000031113502024172023353 0ustar jjjj# #=DESCRIPTION allow change_profile to a hat with quotes #=EXRESULT PASS # /usr/bin/foo { allow change_profile -> "/bin/foo//bar", } /usr/bin/foo2 { allow change_profile -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_re_bad_6.sd0000644000175000017500000000022313502024172024674 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { owner change_profile @{var} -> *//ab, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/da_bare_bad_1.sd0000644000175000017500000000015313502024172023725 0ustar jjjj# #=DESCRIPTION deny audit in wrong order #=EXRESULT FAIL # /usr/bin/foo { deny audit change_profile, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_bare_ok_1.sd0000644000175000017500000000017213502024172025045 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} #=EXRESULT PASS # @{var}=/test /usr/bin/foo { deny change_profile @{var}, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/unsafe_bad_2.sd0000644000175000017500000000021413502024172023630 0ustar jjjj# #=DESCRIPTION change_profile w/ unsafe modifier but no exec condition #=EXRESULT FAIL # /usr/bin/foo { change_profile unsafe -> baz, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_bad_1.sd0000644000175000017500000000021713502024172023634 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit owner change_profile /onexec -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_ok_5.sd0000644000175000017500000000037713502024172024230 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { audit deny change_profile @{var} -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/re_ok_2.sd0000644000175000017500000000172113502024172022644 0ustar jjjj# #=DESCRIPTION change_profile to a hat #=EXRESULT PASS # /usr/bin/foo { change_profile -> /bin/foo//bar, } /usr/bin/foo2 { change_profile -> /bin/foo//ba*, } /usr/bin/foo3 { change_profile -> /bin/foo//ba**, } /usr/bin/foo4 { change_profile -> /bin/foo//ba?, } /usr/bin/foo5 { change_profile -> /bin/foo//ba[ab], } /usr/bin/foo6 { change_profile -> /bin/foo//ba[^ab], } /usr/bin/foo7 { change_profile -> /bin/fo*//bar, } /usr/bin/foo8 { change_profile -> /bin/fo**//bar, } /usr/bin/foo9 { change_profile -> /bin/fo?//bar, } /usr/bin/foo10 { change_profile -> /bin/fo[ab]//bar, } /usr/bin/foo11 { change_profile -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { change_profile -> /bin/fo*//ba*, } /usr/bin/foo13 { change_profile -> /bin/fo**//ba**, } /usr/bin/foo14 { change_profile -> /bin/fo?//ba?, } /usr/bin/foo15 { change_profile -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { change_profile -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aa_ok_4.sd0000644000175000017500000000026413502024172022622 0ustar jjjj# #=DESCRIPTION audit allow change_profile with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { audit allow change_profile -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/do_bare_bad_1.sd0000644000175000017500000000016513502024172023746 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile #=EXRESULT FAIL # /usr/bin/foo { deny owner change_profile, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_aao_re_bad_7.sd0000644000175000017500000000024013502024172025176 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit allow owner change_profile @{var} -> :ab:*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_re_ok_6.sd0000644000175000017500000000177013502024172024043 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec with just res, child profile #=EXRESULT PASS # /usr/bin/foo { deny change_profile /onexec -> *//ab, } /usr/bin/foo2 { deny change_profile /onexec -> **//ab, } /usr/bin/foo3 { deny change_profile /onexec -> ?//ab, } /usr/bin/foo4 { deny change_profile /onexec -> [ab]//ab, } /usr/bin/foo5 { deny change_profile /onexec -> [^ab]//ab, } /usr/bin/foo6 { deny change_profile /onexec -> ab//*, } /usr/bin/foo7 { deny change_profile /onexec -> ab//**, } /usr/bin/foo8 { deny change_profile /onexec -> ab//?, } /usr/bin/foo9 { deny change_profile /onexec -> ab//[ab], } /usr/bin/foo10 { deny change_profile /onexec -> ab//[^ab], } /usr/bin/foo11 { deny change_profile /onexec -> *//*, } /usr/bin/foo12 { deny change_profile /onexec -> **//*, } /usr/bin/foo13 { deny change_profile /onexec -> ?//*, } /usr/bin/foo14 { deny change_profile /onexec -> [ab]//*, } /usr/bin/foo15 { deny change_profile /onexec -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_aao_bad_7.sd0000644000175000017500000000025013502024172024511 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit allow owner change_profile @{var} -> "/bin/foo//bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_re_bad_8.sd0000644000175000017500000000022113502024172024324 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo5 { audit owner change_profile /onexec -> "/bin/*", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aao_bad_8.sd0000644000175000017500000000023513502024172024004 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit allow owner change_profile /onexec -> ":foo:/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_re_bad_7.sd0000644000175000017500000000021013502024172024160 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { owner change_profile /onexec -> :ab:*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aa_re_ok_5.sd0000644000175000017500000000062613502024172024177 0ustar jjjj# #=DESCRIPTION audit allow change_profile /onexec with just res #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile /onexec -> *, } /usr/bin/foo2 { audit allow change_profile /onexec -> **, } /usr/bin/foo3 { audit allow change_profile /onexec -> ?, } /usr/bin/foo4 { audit allow change_profile /onexec -> [ab], } /usr/bin/foo5 { audit allow change_profile /onexec -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_re_ok_4.sd0000644000175000017500000000175513502024172024205 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { audit deny change_profile /onexec -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { audit deny change_profile /onexec -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { audit deny change_profile /onexec -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { audit deny change_profile /onexec -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { audit deny change_profile /onexec -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { audit deny change_profile /onexec -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { audit deny change_profile /onexec -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { audit deny change_profile /onexec -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { audit deny change_profile /onexec -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { audit deny change_profile /onexec -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { audit deny change_profile /onexec -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aao_re_bad_1.sd0000644000175000017500000000022313502024172024460 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit allow owner change_profile /onexec -> /bin/*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_re_ok_1.sd0000644000175000017500000000055213502024172023310 0ustar jjjj# #=DESCRIPTION audit deny change_profile #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile -> /bin/*, } /usr/bin/foo2 { audit deny change_profile -> /bin/**, } /usr/bin/foo3 { audit deny change_profile -> /bin/?, } /usr/bin/foo4 { audit deny change_profile -> /bin/[ab], } /usr/bin/foo5 { audit deny change_profile -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_re_ok_8.sd0000644000175000017500000000125713502024172024253 0ustar jjjj# #=DESCRIPTION change_profile @{var} re with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo5 { change_profile @{var} -> "/bin/*", } /usr/bin/foo6 { change_profile @{var} -> "/bin/**", } /usr/bin/foo7 { change_profile @{var} -> "/bin/[ab]", } /usr/bin/foo8 { change_profile @{var} -> "/bin/[^ab]", } /usr/bin/foo10 { change_profile @{var} -> "/bin/?ab", } /usr/bin/foo11 { change_profile @{var} -> "/bin/ *", } /usr/bin/foo12 { change_profile @{var} -> "/bin/ **", } /usr/bin/foo13 { change_profile @{var} -> "/bin/ [ab]", } /usr/bin/foo14 { change_profile @{var} -> "/bin/ [^ab]", } /usr/bin/foo15 { change_profile @{var} -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ok_5.sd0000644000175000017500000000031613502024172022160 0ustar jjjj# #=DESCRIPTION change_profile with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/bare_ok_1.sd0000644000175000017500000000012513502024172023143 0ustar jjjj# #=DESCRIPTION change_profile #=EXRESULT PASS # /usr/bin/foo { change_profile, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_re_bad_1.sd0000644000175000017500000000022313502024172024667 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { owner change_profile @{var} -> /bin/*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_bad_4.sd0000644000175000017500000000027013502024172024347 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { audit owner change_profile @{var} -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_re_bad_6.sd0000644000175000017500000000022213502024172024467 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit deny owner change_profile /onexec -> *//ab, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_bad_5.sd0000644000175000017500000000034313502024172024336 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { deny audit change_profile @{var} -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_re_ok_3.sd0000644000175000017500000000243113502024172024174 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec with name space #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile /onexec -> :foo:/bin/foo, } /usr/bin/foo2 { audit deny change_profile /onexec -> :foo:/bin/fo*, } /usr/bin/foo3 { audit deny change_profile /onexec -> :foo:/bin/fo**, } /usr/bin/foo4 { audit deny change_profile /onexec -> :foo:/bin/fo?, } /usr/bin/foo5 { audit deny change_profile /onexec -> :foo:/bin/fo[ab], } /usr/bin/foo6 { audit deny change_profile /onexec -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { audit deny change_profile /onexec -> :fo*:/bin/foo, } /usr/bin/foo8 { audit deny change_profile /onexec -> :fo**:/bin/foo, } /usr/bin/foo9 { audit deny change_profile /onexec -> :fo?:/bin/foo, } /usr/bin/foo10 { audit deny change_profile /onexec -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { audit deny change_profile /onexec -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { audit deny change_profile /onexec -> :fo*:/bin/fo*, } /usr/bin/foo13 { audit deny change_profile /onexec -> :fo**:/bin/fo**, } /usr/bin/foo14 { audit deny change_profile /onexec -> :fo?:/bin/fo?, } /usr/bin/foo15 { audit deny change_profile /onexec -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { audit deny change_profile /onexec -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_re_bad_7.sd0000644000175000017500000000021513502024172024331 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { deny owner change_profile /onexec -> :ab:*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_re_bad_6.sd0000644000175000017500000000023013502024172025036 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny owner change_profile @{var} -> *//ab, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ok_4.sd0000644000175000017500000000026713502024172023561 0ustar jjjj# #=DESCRIPTION change_profile @{var} with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { change_profile @{var} -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_bad_3.sd0000644000175000017500000000021613502024172023474 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { owner change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_ok_2.sd0000644000175000017500000000017113502024172022457 0ustar jjjj# #=DESCRIPTION deny change_profile to a hat #=EXRESULT PASS # /usr/bin/foo { deny change_profile -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_bad_3.sd0000644000175000017500000000022313502024172023636 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { deny owner change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_bad_7.sd0000644000175000017500000000023713502024172024342 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny audit change_profile @{var} -> "/bin/foo//bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_bad_3.sd0000644000175000017500000000022413502024172023634 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit owner change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allow_re_ok_7.sd0000644000175000017500000000161313502024172024047 0ustar jjjj# #=DESCRIPTION allow change_profile with just re, namespace #=EXRESULT PASS # /usr/bin/foo { allow change_profile -> :ab:*, } /usr/bin/foo2 { allow change_profile -> :ab:**, } /usr/bin/foo3 { allow change_profile -> :ab:?, } /usr/bin/foo4 { allow change_profile -> :ab:[ab], } /usr/bin/foo5 { allow change_profile -> :ab:[^ab], } /usr/bin/foo6 { allow change_profile -> :*:ab, } /usr/bin/foo7 { allow change_profile -> :**:ab, } /usr/bin/foo8 { allow change_profile -> :?:ab, } /usr/bin/foo9 { allow change_profile -> :[ab]:ab, } /usr/bin/foo10 { allow change_profile -> :[^ab]:ab, } /usr/bin/foo11 { allow change_profile -> :*:*, } /usr/bin/foo12 { allow change_profile -> :**:**, } /usr/bin/foo13 { allow change_profile -> :?:?, } /usr/bin/foo14 { allow change_profile -> :[ab]:[ab], } /usr/bin/foo15 { allow change_profile -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_ok_4.sd0000644000175000017500000000026213502024172022623 0ustar jjjj# #=DESCRIPTION audit deny change_profile with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { audit deny change_profile -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_allow_ok_2.sd0000644000175000017500000000021313502024172024233 0ustar jjjj# #=DESCRIPTION allow change_profile /onexec to a hat #=EXRESULT PASS # /usr/bin/foo { allow change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_re_bad_1.sd0000644000175000017500000000023613502024172025200 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit deny owner change_profile @{var} -> /bin/*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_re_bad_7.sd0000644000175000017500000000023113502024172025040 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny owner change_profile @{var} -> :ab:*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_bad_2.sd0000644000175000017500000000022113502024172023615 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # /usr/bin/foo { deny audit change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_ok_7.sd0000644000175000017500000000034113502024172023344 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec to a hat with quotes #=EXRESULT PASS # /usr/bin/foo { audit change_profile /onexec -> "/bin/foo//bar", } /usr/bin/foo2 { audit change_profile /onexec -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_re_bad_4.sd0000644000175000017500000000026513502024172024315 0ustar jjjj# #=DESCRIPTION deny audit in wrong order #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { deny audit change_profile /onexec -> @{LIBVIRT}-fo*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_allow_re_ok_7.sd0000644000175000017500000000201313502024172024726 0ustar jjjj# #=DESCRIPTION allow change_profile /onexec with just re, namespace #=EXRESULT PASS # /usr/bin/foo { allow change_profile /onexec -> :ab:*, } /usr/bin/foo2 { allow change_profile /onexec -> :ab:**, } /usr/bin/foo3 { allow change_profile /onexec -> :ab:?, } /usr/bin/foo4 { allow change_profile /onexec -> :ab:[ab], } /usr/bin/foo5 { allow change_profile /onexec -> :ab:[^ab], } /usr/bin/foo6 { allow change_profile /onexec -> :*:ab, } /usr/bin/foo7 { allow change_profile /onexec -> :**:ab, } /usr/bin/foo8 { allow change_profile /onexec -> :?:ab, } /usr/bin/foo9 { allow change_profile /onexec -> :[ab]:ab, } /usr/bin/foo10 { allow change_profile /onexec -> :[^ab]:ab, } /usr/bin/foo11 { allow change_profile /onexec -> :*:*, } /usr/bin/foo12 { allow change_profile /onexec -> :**:**, } /usr/bin/foo13 { allow change_profile /onexec -> :?:?, } /usr/bin/foo14 { allow change_profile /onexec -> :[ab]:[ab], } /usr/bin/foo15 { allow change_profile /onexec -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_bare_ok_1.sd0000644000175000017500000000013713502024172023451 0ustar jjjj# #=DESCRIPTION deny change_profile #=EXRESULT PASS # /usr/bin/foo { deny change_profile, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_aao_re_bad_2.sd0000644000175000017500000000024613502024172025177 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit allow owner change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aao_bad_6.sd0000644000175000017500000000021213502024172023111 0ustar jjjj# #=DESCRIPTION owner not allowed on change_profile #=EXRESULT FAIL # /usr/bin/foo { audit allow owner change_profile -> "/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_re_bad_8.sd0000644000175000017500000000022013502024172024326 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo5 { deny owner change_profile /onexec -> "/bin/*", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_allow_ok_7.sd0000644000175000017500000000035313502024172024756 0ustar jjjj# #=DESCRIPTION allow change_profile @{var} to a hat with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo { allow change_profile @{var} -> "/bin/foo//bar", } /usr/bin/foo2 { allow change_profile @{var} -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_bad_6.sd0000644000175000017500000000022113502024172023634 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit owner change_profile /onexec -> "/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_re_ok_6.sd0000644000175000017500000000200513502024172024541 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} with just res, child profile #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit change_profile @{var} -> *//ab, } /usr/bin/foo2 { audit change_profile @{var} -> **//ab, } /usr/bin/foo3 { audit change_profile @{var} -> ?//ab, } /usr/bin/foo4 { audit change_profile @{var} -> [ab]//ab, } /usr/bin/foo5 { audit change_profile @{var} -> [^ab]//ab, } /usr/bin/foo6 { audit change_profile @{var} -> ab//*, } /usr/bin/foo7 { audit change_profile @{var} -> ab//**, } /usr/bin/foo8 { audit change_profile @{var} -> ab//?, } /usr/bin/foo9 { audit change_profile @{var} -> ab//[ab], } /usr/bin/foo10 { audit change_profile @{var} -> ab//[^ab], } /usr/bin/foo11 { audit change_profile @{var} -> *//*, } /usr/bin/foo12 { audit change_profile @{var} -> **//*, } /usr/bin/foo13 { audit change_profile @{var} -> ?//*, } /usr/bin/foo14 { audit change_profile @{var} -> [ab]//*, } /usr/bin/foo15 { audit change_profile @{var} -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_re_ok_7.sd0000644000175000017500000000165313502024172023541 0ustar jjjj# #=DESCRIPTION change_profile /onexec with just re, namespace #=EXRESULT PASS # /usr/bin/foo { change_profile /onexec -> :ab:*, } /usr/bin/foo2 { change_profile /onexec -> :ab:**, } /usr/bin/foo3 { change_profile /onexec -> :ab:?, } /usr/bin/foo4 { change_profile /onexec -> :ab:[ab], } /usr/bin/foo5 { change_profile /onexec -> :ab:[^ab], } /usr/bin/foo6 { change_profile /onexec -> :*:ab, } /usr/bin/foo7 { change_profile /onexec -> :**:ab, } /usr/bin/foo8 { change_profile /onexec -> :?:ab, } /usr/bin/foo9 { change_profile /onexec -> :[ab]:ab, } /usr/bin/foo10 { change_profile /onexec -> :[^ab]:ab, } /usr/bin/foo11 { change_profile /onexec -> :*:*, } /usr/bin/foo12 { change_profile /onexec -> :**:**, } /usr/bin/foo13 { change_profile /onexec -> :?:?, } /usr/bin/foo14 { change_profile /onexec -> :[ab]:[ab], } /usr/bin/foo15 { change_profile /onexec -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_allow_re_ok_8.sd0000644000175000017500000000135613502024172024740 0ustar jjjj# #=DESCRIPTION allow change_profile /onexec re with quotes #=EXRESULT PASS # /usr/bin/foo5 { allow change_profile /onexec -> "/bin/*", } /usr/bin/foo6 { allow change_profile /onexec -> "/bin/**", } /usr/bin/foo7 { allow change_profile /onexec -> "/bin/[ab]", } /usr/bin/foo8 { allow change_profile /onexec -> "/bin/[^ab]", } /usr/bin/foo10 { allow change_profile /onexec -> "/bin/?ab", } /usr/bin/foo11 { allow change_profile /onexec -> "/bin/ *", } /usr/bin/foo12 { allow change_profile /onexec -> "/bin/ **", } /usr/bin/foo13 { allow change_profile /onexec -> "/bin/ [ab]", } /usr/bin/foo14 { allow change_profile /onexec -> "/bin/ [^ab]", } /usr/bin/foo15 { allow change_profile /onexec -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_re_bad_3.sd0000644000175000017500000000023113502024172024464 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit deny owner change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_bad_1.sd0000644000175000017500000000021613502024172023636 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { deny owner change_profile /onexec -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_re_bad_6.sd0000644000175000017500000000023113502024172025034 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit owner change_profile @{var} -> *//ab, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_re_ok_6.sd0000644000175000017500000000161013502024172023145 0ustar jjjj# #=DESCRIPTION audit change_profile with just res, child profile #=EXRESULT PASS # /usr/bin/foo { audit change_profile -> *//ab, } /usr/bin/foo2 { audit change_profile -> **//ab, } /usr/bin/foo3 { audit change_profile -> ?//ab, } /usr/bin/foo4 { audit change_profile -> [ab]//ab, } /usr/bin/foo5 { audit change_profile -> [^ab]//ab, } /usr/bin/foo6 { audit change_profile -> ab//*, } /usr/bin/foo7 { audit change_profile -> ab//**, } /usr/bin/foo8 { audit change_profile -> ab//?, } /usr/bin/foo9 { audit change_profile -> ab//[ab], } /usr/bin/foo10 { audit change_profile -> ab//[^ab], } /usr/bin/foo11 { audit change_profile -> *//*, } /usr/bin/foo12 { audit change_profile -> **//*, } /usr/bin/foo13 { audit change_profile -> ?//*, } /usr/bin/foo14 { audit change_profile -> [ab]//*, } /usr/bin/foo15 { audit change_profile -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_bad_4.sd0000644000175000017500000000027513502024172024520 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { audit deny owner change_profile @{var} -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_allow_re_ok_5.sd0000644000175000017500000000056213502024172024733 0ustar jjjj# #=DESCRIPTION allow change_profile /onexec with just res #=EXRESULT PASS # /usr/bin/foo { allow change_profile /onexec -> *, } /usr/bin/foo2 { allow change_profile /onexec -> **, } /usr/bin/foo3 { allow change_profile /onexec -> ?, } /usr/bin/foo4 { allow change_profile /onexec -> [ab], } /usr/bin/foo5 { allow change_profile /onexec -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_re_ok_4.sd0000644000175000017500000000164613502024172024554 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" @{var}=/test /usr/bin/foo { deny change_profile @{var} -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { deny change_profile @{var} -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { deny change_profile @{var} -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { deny change_profile @{var} -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { deny change_profile @{var} -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { deny change_profile @{var} -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { deny change_profile @{var} -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { deny change_profile @{var} -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { deny change_profile @{var} -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { deny change_profile @{var} -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { deny change_profile @{var} -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_re_ok_2.sd0000644000175000017500000000221413502024172023306 0ustar jjjj# #=DESCRIPTION audit deny change_profile to a hat #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile -> /bin/foo//bar, } /usr/bin/foo2 { audit deny change_profile -> /bin/foo//ba*, } /usr/bin/foo3 { audit deny change_profile -> /bin/foo//ba**, } /usr/bin/foo4 { audit deny change_profile -> /bin/foo//ba?, } /usr/bin/foo5 { audit deny change_profile -> /bin/foo//ba[ab], } /usr/bin/foo6 { audit deny change_profile -> /bin/foo//ba[^ab], } /usr/bin/foo7 { audit deny change_profile -> /bin/fo*//bar, } /usr/bin/foo8 { audit deny change_profile -> /bin/fo**//bar, } /usr/bin/foo9 { audit deny change_profile -> /bin/fo?//bar, } /usr/bin/foo10 { audit deny change_profile -> /bin/fo[ab]//bar, } /usr/bin/foo11 { audit deny change_profile -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { audit deny change_profile -> /bin/fo*//ba*, } /usr/bin/foo13 { audit deny change_profile -> /bin/fo**//ba**, } /usr/bin/foo14 { audit deny change_profile -> /bin/fo?//ba?, } /usr/bin/foo15 { audit deny change_profile -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { audit deny change_profile -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aa_ok_6.sd0000644000175000017500000000034013502024172023503 0ustar jjjj# #=DESCRIPTION audit allow change_profile /onexec with quotes #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile /onexec -> "/bin/foo", } /usr/bin/foo2 { audit allow change_profile /onexec -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_bad_7.sd0000644000175000017500000000024713502024172024522 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit deny owner change_profile @{var} -> "/bin/foo//bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_aao_bad_3.sd0000644000175000017500000000024613502024172024512 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit allow owner change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_ok_5.sd0000644000175000017500000000036313502024172024062 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { deny change_profile @{var} -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_re_ok_5.sd0000644000175000017500000000054013502024172023311 0ustar jjjj# #=DESCRIPTION audit deny change_profile with just res #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile -> *, } /usr/bin/foo2 { audit deny change_profile -> **, } /usr/bin/foo3 { audit deny change_profile -> ?, } /usr/bin/foo4 { audit deny change_profile -> [ab], } /usr/bin/foo5 { audit deny change_profile -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_re_ok_6.sd0000644000175000017500000000176513502024172024560 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} with just res, child profile #=EXRESULT PASS # @{var}=/test /usr/bin/foo { deny change_profile @{var} -> *//ab, } /usr/bin/foo2 { deny change_profile @{var} -> **//ab, } /usr/bin/foo3 { deny change_profile @{var} -> ?//ab, } /usr/bin/foo4 { deny change_profile @{var} -> [ab]//ab, } /usr/bin/foo5 { deny change_profile @{var} -> [^ab]//ab, } /usr/bin/foo6 { deny change_profile @{var} -> ab//*, } /usr/bin/foo7 { deny change_profile @{var} -> ab//**, } /usr/bin/foo8 { deny change_profile @{var} -> ab//?, } /usr/bin/foo9 { deny change_profile @{var} -> ab//[ab], } /usr/bin/foo10 { deny change_profile @{var} -> ab//[^ab], } /usr/bin/foo11 { deny change_profile @{var} -> *//*, } /usr/bin/foo12 { deny change_profile @{var} -> **//*, } /usr/bin/foo13 { deny change_profile @{var} -> ?//*, } /usr/bin/foo14 { deny change_profile @{var} -> [ab]//*, } /usr/bin/foo15 { deny change_profile @{var} -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_bare_ok_1.sd0000644000175000017500000000017413502024172025044 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit change_profile @{var}, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_bad_7.sd0000644000175000017500000000022313502024172023624 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # /usr/bin/foo { deny audit change_profile /onexec -> "/bin/foo//bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_aao_bad_6.sd0000644000175000017500000000024313502024172024512 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit allow owner change_profile @{var} -> "/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/stacking_ok_3.sd0000644000175000017500000000016213502024172024040 0ustar jjjj# #=DESCRIPTION change_profile w/ stacking #=EXRESULT PASS # /usr/bin/foo { change_profile /bin/foo -> &bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_re_bad_7.sd0000644000175000017500000000021613502024172024327 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit owner change_profile /onexec -> :ab:*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_re_ok_2.sd0000644000175000017500000000242413502024172024175 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec to a hat #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile /onexec -> /bin/foo//bar, } /usr/bin/foo2 { audit deny change_profile /onexec -> /bin/foo//ba*, } /usr/bin/foo3 { audit deny change_profile /onexec -> /bin/foo//ba**, } /usr/bin/foo4 { audit deny change_profile /onexec -> /bin/foo//ba?, } /usr/bin/foo5 { audit deny change_profile /onexec -> /bin/foo//ba[ab], } /usr/bin/foo6 { audit deny change_profile /onexec -> /bin/foo//ba[^ab], } /usr/bin/foo7 { audit deny change_profile /onexec -> /bin/fo*//bar, } /usr/bin/foo8 { audit deny change_profile /onexec -> /bin/fo**//bar, } /usr/bin/foo9 { audit deny change_profile /onexec -> /bin/fo?//bar, } /usr/bin/foo10 { audit deny change_profile /onexec -> /bin/fo[ab]//bar, } /usr/bin/foo11 { audit deny change_profile /onexec -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { audit deny change_profile /onexec -> /bin/fo*//ba*, } /usr/bin/foo13 { audit deny change_profile /onexec -> /bin/fo**//ba**, } /usr/bin/foo14 { audit deny change_profile /onexec -> /bin/fo?//ba?, } /usr/bin/foo15 { audit deny change_profile /onexec -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { audit deny change_profile /onexec -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_re_ok_7.sd0000644000175000017500000000165013502024172024247 0ustar jjjj# #=DESCRIPTION change_profile @{var} with just re, namespace #=EXRESULT PASS # @{var}=/test /usr/bin/foo { change_profile @{var} -> :ab:*, } /usr/bin/foo2 { change_profile @{var} -> :ab:**, } /usr/bin/foo3 { change_profile @{var} -> :ab:?, } /usr/bin/foo4 { change_profile @{var} -> :ab:[ab], } /usr/bin/foo5 { change_profile @{var} -> :ab:[^ab], } /usr/bin/foo6 { change_profile @{var} -> :*:ab, } /usr/bin/foo7 { change_profile @{var} -> :**:ab, } /usr/bin/foo8 { change_profile @{var} -> :?:ab, } /usr/bin/foo9 { change_profile @{var} -> :[ab]:ab, } /usr/bin/foo10 { change_profile @{var} -> :[^ab]:ab, } /usr/bin/foo11 { change_profile @{var} -> :*:*, } /usr/bin/foo12 { change_profile @{var} -> :**:**, } /usr/bin/foo13 { change_profile @{var} -> :?:?, } /usr/bin/foo14 { change_profile @{var} -> :[ab]:[ab], } /usr/bin/foo15 { change_profile @{var} -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_re_ok_7.sd0000644000175000017500000000201013502024172024536 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} with just re, namespace #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit change_profile @{var} -> :ab:*, } /usr/bin/foo2 { audit change_profile @{var} -> :ab:**, } /usr/bin/foo3 { audit change_profile @{var} -> :ab:?, } /usr/bin/foo4 { audit change_profile @{var} -> :ab:[ab], } /usr/bin/foo5 { audit change_profile @{var} -> :ab:[^ab], } /usr/bin/foo6 { audit change_profile @{var} -> :*:ab, } /usr/bin/foo7 { audit change_profile @{var} -> :**:ab, } /usr/bin/foo8 { audit change_profile @{var} -> :?:ab, } /usr/bin/foo9 { audit change_profile @{var} -> :[ab]:ab, } /usr/bin/foo10 { audit change_profile @{var} -> :[^ab]:ab, } /usr/bin/foo11 { audit change_profile @{var} -> :*:*, } /usr/bin/foo12 { audit change_profile @{var} -> :**:**, } /usr/bin/foo13 { audit change_profile @{var} -> :?:?, } /usr/bin/foo14 { audit change_profile @{var} -> :[ab]:[ab], } /usr/bin/foo15 { audit change_profile @{var} -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_re_bad_7.sd0000644000175000017500000000017613502024172024321 0ustar jjjj# #=DESCRIPTION deny audit in wrong order #=EXRESULT FAIL # /usr/bin/foo { deny audit change_profile /onexec -> :ab:*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_re_ok_2.sd0000644000175000017500000000206713502024172023150 0ustar jjjj# #=DESCRIPTION audit change_profile to a hat #=EXRESULT PASS # /usr/bin/foo { audit change_profile -> /bin/foo//bar, } /usr/bin/foo2 { audit change_profile -> /bin/foo//ba*, } /usr/bin/foo3 { audit change_profile -> /bin/foo//ba**, } /usr/bin/foo4 { audit change_profile -> /bin/foo//ba?, } /usr/bin/foo5 { audit change_profile -> /bin/foo//ba[ab], } /usr/bin/foo6 { audit change_profile -> /bin/foo//ba[^ab], } /usr/bin/foo7 { audit change_profile -> /bin/fo*//bar, } /usr/bin/foo8 { audit change_profile -> /bin/fo**//bar, } /usr/bin/foo9 { audit change_profile -> /bin/fo?//bar, } /usr/bin/foo10 { audit change_profile -> /bin/fo[ab]//bar, } /usr/bin/foo11 { audit change_profile -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { audit change_profile -> /bin/fo*//ba*, } /usr/bin/foo13 { audit change_profile -> /bin/fo**//ba**, } /usr/bin/foo14 { audit change_profile -> /bin/fo?//ba?, } /usr/bin/foo15 { audit change_profile -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { audit change_profile -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/re_ok_6.sd0000644000175000017500000000145013502024172022647 0ustar jjjj# #=DESCRIPTION change_profile with just res, child profile #=EXRESULT PASS # /usr/bin/foo { change_profile -> *//ab, } /usr/bin/foo2 { change_profile -> **//ab, } /usr/bin/foo3 { change_profile -> ?//ab, } /usr/bin/foo4 { change_profile -> [ab]//ab, } /usr/bin/foo5 { change_profile -> [^ab]//ab, } /usr/bin/foo6 { change_profile -> ab//*, } /usr/bin/foo7 { change_profile -> ab//**, } /usr/bin/foo8 { change_profile -> ab//?, } /usr/bin/foo9 { change_profile -> ab//[ab], } /usr/bin/foo10 { change_profile -> ab//[^ab], } /usr/bin/foo11 { change_profile -> *//*, } /usr/bin/foo12 { change_profile -> **//*, } /usr/bin/foo13 { change_profile -> ?//*, } /usr/bin/foo14 { change_profile -> [ab]//*, } /usr/bin/foo15 { change_profile -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_re_bad_8.sd0000644000175000017500000000022613502024172024475 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo5 { audit deny owner change_profile /onexec -> "/bin/*", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allow_ok_4.sd0000644000175000017500000000025013502024172023352 0ustar jjjj# #=DESCRIPTION allow change_profile with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { allow change_profile -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aao_re_bad_5.sd0000644000175000017500000000022013502024172024461 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit allow owner change_profile /onexec -> *, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aa_ok_2.sd0000644000175000017500000000022713502024172023503 0ustar jjjj# #=DESCRIPTION audit allow change_profile /onexec to a hat #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_ok_3.sd0000644000175000017500000000023313502024172024054 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} with name space #=EXRESULT PASS # @{var}=/test /usr/bin/foo { deny change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_allow_ok_5.sd0000644000175000017500000000036513502024172024757 0ustar jjjj# #=DESCRIPTION allow change_profile @{var} with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { allow change_profile @{var} -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_re_bad_8.sd0000644000175000017500000000021713502024172025045 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo5 { deny owner change_profile @{var} -> "/bin/*", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_ok_8.sd0000644000175000017500000000032013502024172022456 0ustar jjjj# #=DESCRIPTION audit change_profile with name space with quotes #=EXRESULT PASS # /usr/bin/foo { audit change_profile -> ":foo:/bin/foo", } /usr/bin/foo2 { audit change_profile -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_re_bad_1.sd0000644000175000017500000000020713502024172024160 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { owner change_profile /onexec -> /bin/*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_allow_re_ok_1.sd0000644000175000017500000000060313502024172025434 0ustar jjjj# #=DESCRIPTION allow change_profile @{var} #=EXRESULT PASS # @{var}=/test /usr/bin/foo { allow change_profile @{var} -> /bin/*, } /usr/bin/foo2 { allow change_profile @{var} -> /bin/**, } /usr/bin/foo3 { allow change_profile @{var} -> /bin/?, } /usr/bin/foo4 { allow change_profile @{var} -> /bin/[ab], } /usr/bin/foo5 { allow change_profile @{var} -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_allow_ok_5.sd0000644000175000017500000000035213502024172024242 0ustar jjjj# #=DESCRIPTION allow change_profile /onexec with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { allow change_profile /onexec -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_re_ok_1.sd0000644000175000017500000000056613502024172024040 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec #=EXRESULT PASS # /usr/bin/foo { deny change_profile /onexec -> /bin/*, } /usr/bin/foo2 { deny change_profile /onexec -> /bin/**, } /usr/bin/foo3 { deny change_profile /onexec -> /bin/?, } /usr/bin/foo4 { deny change_profile /onexec -> /bin/[ab], } /usr/bin/foo5 { deny change_profile /onexec -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_bad_3.sd0000644000175000017500000000022113502024172023616 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # /usr/bin/foo { deny audit change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_re_ok_5.sd0000644000175000017500000000055413502024172024041 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec with just res #=EXRESULT PASS # /usr/bin/foo { deny change_profile /onexec -> *, } /usr/bin/foo2 { deny change_profile /onexec -> **, } /usr/bin/foo3 { deny change_profile /onexec -> ?, } /usr/bin/foo4 { deny change_profile /onexec -> [ab], } /usr/bin/foo5 { deny change_profile /onexec -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_bad_7.sd0000644000175000017500000000022013502024172023473 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { owner change_profile /onexec -> "/bin/foo//bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_ok_6.sd0000644000175000017500000000032513502024172024061 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo { deny change_profile @{var} -> "/bin/foo", } /usr/bin/foo2 { deny change_profile @{var} -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allow_ok_2.sd0000644000175000017500000000017313502024172023354 0ustar jjjj# #=DESCRIPTION allow change_profile to a hat #=EXRESULT PASS # /usr/bin/foo { allow change_profile -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_ok_6.sd0000644000175000017500000000031313502024172023345 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec with quotes #=EXRESULT PASS # /usr/bin/foo { deny change_profile /onexec -> "/bin/foo", } /usr/bin/foo2 { deny change_profile /onexec -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_ok_1.sd0000644000175000017500000000015313502024172022456 0ustar jjjj# #=DESCRIPTION deny change_profile #=EXRESULT PASS # /usr/bin/foo { deny change_profile -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/re_ok_4.sd0000644000175000017500000000141113502024172022642 0ustar jjjj# #=DESCRIPTION change_profile with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { change_profile -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { change_profile -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { change_profile -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { change_profile -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { change_profile -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { change_profile -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { change_profile -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { change_profile -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { change_profile -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { change_profile -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { change_profile -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aa_ok_7.sd0000644000175000017500000000033313502024172022622 0ustar jjjj# #=DESCRIPTION audit allow change_profile to a hat with quotes #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile -> "/bin/foo//bar", } /usr/bin/foo2 { audit allow change_profile -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_re_ok_7.sd0000644000175000017500000000173313502024172023320 0ustar jjjj# #=DESCRIPTION audit deny change_profile with just re, namespace #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile -> :ab:*, } /usr/bin/foo2 { audit deny change_profile -> :ab:**, } /usr/bin/foo3 { audit deny change_profile -> :ab:?, } /usr/bin/foo4 { audit deny change_profile -> :ab:[ab], } /usr/bin/foo5 { audit deny change_profile -> :ab:[^ab], } /usr/bin/foo6 { audit deny change_profile -> :*:ab, } /usr/bin/foo7 { audit deny change_profile -> :**:ab, } /usr/bin/foo8 { audit deny change_profile -> :?:ab, } /usr/bin/foo9 { audit deny change_profile -> :[ab]:ab, } /usr/bin/foo10 { audit deny change_profile -> :[^ab]:ab, } /usr/bin/foo11 { audit deny change_profile -> :*:*, } /usr/bin/foo12 { audit deny change_profile -> :**:**, } /usr/bin/foo13 { audit deny change_profile -> :?:?, } /usr/bin/foo14 { audit deny change_profile -> :[ab]:[ab], } /usr/bin/foo15 { audit deny change_profile -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aa_ok_3.sd0000644000175000017500000000023613502024172023504 0ustar jjjj# #=DESCRIPTION audit allow change_profile /onexec with name space #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/safe_bad_1.sd0000644000175000017500000000020113502024172023260 0ustar jjjj# #=DESCRIPTION change_profile w/ safe modifier but no exec condition #=EXRESULT FAIL # /usr/bin/foo { change_profile safe, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_bad_3.sd0000644000175000017500000000023513502024172024334 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny audit change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_bare_ok_1.sd0000644000175000017500000000015713502024172024337 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec #=EXRESULT PASS # /usr/bin/foo { deny change_profile /onexec, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_allow_ok_3.sd0000644000175000017500000000022213502024172024234 0ustar jjjj# #=DESCRIPTION allow change_profile /onexec with name space #=EXRESULT PASS # /usr/bin/foo { allow change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_re_ok_1.sd0000644000175000017500000000057513502024172024551 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} #=EXRESULT PASS # @{var}=/test /usr/bin/foo { deny change_profile @{var} -> /bin/*, } /usr/bin/foo2 { deny change_profile @{var} -> /bin/**, } /usr/bin/foo3 { deny change_profile @{var} -> /bin/?, } /usr/bin/foo4 { deny change_profile @{var} -> /bin/[ab], } /usr/bin/foo5 { deny change_profile @{var} -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_re_bad_5.sd0000644000175000017500000000023213502024172025200 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit deny owner change_profile @{var} -> *, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_bad_1.sd0000644000175000017500000000022513502024172024203 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { owner change_profile @{var} -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_re_ok_3.sd0000644000175000017500000000230013502024172024534 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} with name space #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit change_profile @{var} -> :foo:/bin/foo, } /usr/bin/foo2 { audit change_profile @{var} -> :foo:/bin/fo*, } /usr/bin/foo3 { audit change_profile @{var} -> :foo:/bin/fo**, } /usr/bin/foo4 { audit change_profile @{var} -> :foo:/bin/fo?, } /usr/bin/foo5 { audit change_profile @{var} -> :foo:/bin/fo[ab], } /usr/bin/foo6 { audit change_profile @{var} -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { audit change_profile @{var} -> :fo*:/bin/foo, } /usr/bin/foo8 { audit change_profile @{var} -> :fo**:/bin/foo, } /usr/bin/foo9 { audit change_profile @{var} -> :fo?:/bin/foo, } /usr/bin/foo10 { audit change_profile @{var} -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { audit change_profile @{var} -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { audit change_profile @{var} -> :fo*:/bin/fo*, } /usr/bin/foo13 { audit change_profile @{var} -> :fo**:/bin/fo**, } /usr/bin/foo14 { audit change_profile @{var} -> :fo?:/bin/fo?, } /usr/bin/foo15 { audit change_profile @{var} -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { audit change_profile @{var} -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_ok_7.sd0000644000175000017500000000035313502024172024060 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} to a hat with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit change_profile @{var} -> "/bin/foo//bar", } /usr/bin/foo2 { audit change_profile @{var} -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/re_ok_3.sd0000644000175000017500000000172613502024172022652 0ustar jjjj# #=DESCRIPTION change_profile with name space #=EXRESULT PASS # /usr/bin/foo { change_profile -> :foo:/bin/foo, } /usr/bin/foo2 { change_profile -> :foo:/bin/fo*, } /usr/bin/foo3 { change_profile -> :foo:/bin/fo**, } /usr/bin/foo4 { change_profile -> :foo:/bin/fo?, } /usr/bin/foo5 { change_profile -> :foo:/bin/fo[ab], } /usr/bin/foo6 { change_profile -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { change_profile -> :fo*:/bin/foo, } /usr/bin/foo8 { change_profile -> :fo**:/bin/foo, } /usr/bin/foo9 { change_profile -> :fo?:/bin/foo, } /usr/bin/foo10 { change_profile -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { change_profile -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { change_profile -> :fo*:/bin/fo*, } /usr/bin/foo13 { change_profile -> :fo**:/bin/fo**, } /usr/bin/foo14 { change_profile -> :fo?:/bin/fo?, } /usr/bin/foo15 { change_profile -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { change_profile -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_ok_3.sd0000644000175000017500000000021413502024172022617 0ustar jjjj# #=DESCRIPTION audit deny change_profile with name space #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_ok_8.sd0000644000175000017500000000040113502024172024217 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} with name space with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit deny change_profile @{var} -> ":foo:/bin/foo", } /usr/bin/foo2 { audit deny change_profile @{var} -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_re_bad_4.sd0000644000175000017500000000032013502024172025034 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" @{var}=/test /usr/bin/foo { deny owner change_profile @{var} -> @{LIBVIRT}-fo*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aa_ok_6.sd0000644000175000017500000000031013502024172022614 0ustar jjjj# #=DESCRIPTION audit allow change_profile with quotes #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile -> "/bin/foo", } /usr/bin/foo2 { audit allow change_profile -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_bad_5.sd0000644000175000017500000000033213502024172023636 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" /usr/bin/foo { audit owner change_profile /onexec -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aa_ok_1.sd0000644000175000017500000000017113502024172022614 0ustar jjjj# #=DESCRIPTION audit allow change_profile #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_ok_1.sd0000644000175000017500000000017313502024172023344 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec #=EXRESULT PASS # /usr/bin/foo { deny change_profile /onexec -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_re_ok_3.sd0000644000175000017500000000213213502024172024237 0ustar jjjj# #=DESCRIPTION change_profile @{var} with name space #=EXRESULT PASS # @{var}=/test /usr/bin/foo { change_profile @{var} -> :foo:/bin/foo, } /usr/bin/foo2 { change_profile @{var} -> :foo:/bin/fo*, } /usr/bin/foo3 { change_profile @{var} -> :foo:/bin/fo**, } /usr/bin/foo4 { change_profile @{var} -> :foo:/bin/fo?, } /usr/bin/foo5 { change_profile @{var} -> :foo:/bin/fo[ab], } /usr/bin/foo6 { change_profile @{var} -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { change_profile @{var} -> :fo*:/bin/foo, } /usr/bin/foo8 { change_profile @{var} -> :fo**:/bin/foo, } /usr/bin/foo9 { change_profile @{var} -> :fo?:/bin/foo, } /usr/bin/foo10 { change_profile @{var} -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { change_profile @{var} -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { change_profile @{var} -> :fo*:/bin/fo*, } /usr/bin/foo13 { change_profile @{var} -> :fo**:/bin/fo**, } /usr/bin/foo14 { change_profile @{var} -> :fo?:/bin/fo?, } /usr/bin/foo15 { change_profile @{var} -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { change_profile @{var} -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_re_ok_3.sd0000644000175000017500000000205313502024172023147 0ustar jjjj# #=DESCRIPTION deny change_profile with name space #=EXRESULT PASS # /usr/bin/foo { deny change_profile -> :foo:/bin/foo, } /usr/bin/foo2 { deny change_profile -> :foo:/bin/fo*, } /usr/bin/foo3 { deny change_profile -> :foo:/bin/fo**, } /usr/bin/foo4 { deny change_profile -> :foo:/bin/fo?, } /usr/bin/foo5 { deny change_profile -> :foo:/bin/fo[ab], } /usr/bin/foo6 { deny change_profile -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { deny change_profile -> :fo*:/bin/foo, } /usr/bin/foo8 { deny change_profile -> :fo**:/bin/foo, } /usr/bin/foo9 { deny change_profile -> :fo?:/bin/foo, } /usr/bin/foo10 { deny change_profile -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { deny change_profile -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { deny change_profile -> :fo*:/bin/fo*, } /usr/bin/foo13 { deny change_profile -> :fo**:/bin/fo**, } /usr/bin/foo14 { deny change_profile -> :fo?:/bin/fo?, } /usr/bin/foo15 { deny change_profile -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { deny change_profile -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_allow_re_ok_7.sd0000644000175000017500000000201013502024172025434 0ustar jjjj# #=DESCRIPTION allow change_profile @{var} with just re, namespace #=EXRESULT PASS # @{var}=/test /usr/bin/foo { allow change_profile @{var} -> :ab:*, } /usr/bin/foo2 { allow change_profile @{var} -> :ab:**, } /usr/bin/foo3 { allow change_profile @{var} -> :ab:?, } /usr/bin/foo4 { allow change_profile @{var} -> :ab:[ab], } /usr/bin/foo5 { allow change_profile @{var} -> :ab:[^ab], } /usr/bin/foo6 { allow change_profile @{var} -> :*:ab, } /usr/bin/foo7 { allow change_profile @{var} -> :**:ab, } /usr/bin/foo8 { allow change_profile @{var} -> :?:ab, } /usr/bin/foo9 { allow change_profile @{var} -> :[ab]:ab, } /usr/bin/foo10 { allow change_profile @{var} -> :[^ab]:ab, } /usr/bin/foo11 { allow change_profile @{var} -> :*:*, } /usr/bin/foo12 { allow change_profile @{var} -> :**:**, } /usr/bin/foo13 { allow change_profile @{var} -> :?:?, } /usr/bin/foo14 { allow change_profile @{var} -> :[ab]:[ab], } /usr/bin/foo15 { allow change_profile @{var} -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/stacking_ok_2.sd0000644000175000017500000000015113502024172024035 0ustar jjjj# #=DESCRIPTION change_profile w/ stacking #=EXRESULT PASS # /usr/bin/foo { change_profile -> &bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_bad_7.sd0000644000175000017500000000022613502024172023642 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit owner change_profile /onexec -> "/bin/foo//bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_re_bad_5.sd0000644000175000017500000000022213502024172025020 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny audit change_profile @{var} -> *, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_re_ok_4.sd0000644000175000017500000000166213502024172024547 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" @{var}=/test /usr/bin/foo { audit change_profile @{var} -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { audit change_profile @{var} -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { audit change_profile @{var} -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { audit change_profile @{var} -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { audit change_profile @{var} -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { audit change_profile @{var} -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { audit change_profile @{var} -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { audit change_profile @{var} -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { audit change_profile @{var} -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { audit change_profile @{var} -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { audit change_profile @{var} -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_bad_6.sd0000644000175000017500000000024213502024172024514 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit deny owner change_profile @{var} -> "/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ok_3.sd0000644000175000017500000000016613502024172022161 0ustar jjjj# #=DESCRIPTION change_profile with name space #=EXRESULT PASS # /usr/bin/foo { change_profile -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_re_ok_1.sd0000644000175000017500000000060313502024172024536 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit change_profile @{var} -> /bin/*, } /usr/bin/foo2 { audit change_profile @{var} -> /bin/**, } /usr/bin/foo3 { audit change_profile @{var} -> /bin/?, } /usr/bin/foo4 { audit change_profile @{var} -> /bin/[ab], } /usr/bin/foo5 { audit change_profile @{var} -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_bare_bad_1.sd0000644000175000017500000000021713502024172025336 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit owner change_profile @{var}, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_bad_6.sd0000644000175000017500000000022713502024172024212 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { owner change_profile @{var} -> "/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_ok_4.sd0000644000175000017500000000027013502024172023342 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { audit change_profile /onexec -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_re_ok_8.sd0000644000175000017500000000134313502024172024041 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec re with quotes #=EXRESULT PASS # /usr/bin/foo5 { deny change_profile /onexec -> "/bin/*", } /usr/bin/foo6 { deny change_profile /onexec -> "/bin/**", } /usr/bin/foo7 { deny change_profile /onexec -> "/bin/[ab]", } /usr/bin/foo8 { deny change_profile /onexec -> "/bin/[^ab]", } /usr/bin/foo10 { deny change_profile /onexec -> "/bin/?ab", } /usr/bin/foo11 { deny change_profile /onexec -> "/bin/ *", } /usr/bin/foo12 { deny change_profile /onexec -> "/bin/ **", } /usr/bin/foo13 { deny change_profile /onexec -> "/bin/ [ab]", } /usr/bin/foo14 { deny change_profile /onexec -> "/bin/ [^ab]", } /usr/bin/foo15 { deny change_profile /onexec -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_re_ok_8.sd0000644000175000017500000000134613502024172024555 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} re with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo5 { deny change_profile @{var} -> "/bin/*", } /usr/bin/foo6 { deny change_profile @{var} -> "/bin/**", } /usr/bin/foo7 { deny change_profile @{var} -> "/bin/[ab]", } /usr/bin/foo8 { deny change_profile @{var} -> "/bin/[^ab]", } /usr/bin/foo10 { deny change_profile @{var} -> "/bin/?ab", } /usr/bin/foo11 { deny change_profile @{var} -> "/bin/ *", } /usr/bin/foo12 { deny change_profile @{var} -> "/bin/ **", } /usr/bin/foo13 { deny change_profile @{var} -> "/bin/ [ab]", } /usr/bin/foo14 { deny change_profile @{var} -> "/bin/ [^ab]", } /usr/bin/foo15 { deny change_profile @{var} -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aao_re_bad_3.sd0000644000175000017500000000023213502024172024462 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit allow owner change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_bad_6.sd0000644000175000017500000000022613502024172024005 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit deny owner change_profile /onexec -> "/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allowo_bad_1.sd0000644000175000017500000000020013502024172023636 0ustar jjjj# #=DESCRIPTION owner not allow in change_profile #=EXRESULT FAIL # /usr/bin/foo { allow owner change_profile -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_ok_7.sd0000644000175000017500000000033613502024172023353 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec to a hat with quotes #=EXRESULT PASS # /usr/bin/foo { deny change_profile /onexec -> "/bin/foo//bar", } /usr/bin/foo2 { deny change_profile /onexec -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/unsafe_ok_3.sd0000644000175000017500000000023213502024172023514 0ustar jjjj# #=DESCRIPTION change_profile w/ unsafe modifier and "unsafe" target #=EXRESULT PASS # /usr/bin/foo { change_profile unsafe /usr/bin/bar -> unsafe, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aa_re_ok_3.sd0000644000175000017500000000245213502024172024174 0ustar jjjj# #=DESCRIPTION audit allow change_profile /onexec with name space #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile /onexec -> :foo:/bin/foo, } /usr/bin/foo2 { audit allow change_profile /onexec -> :foo:/bin/fo*, } /usr/bin/foo3 { audit allow change_profile /onexec -> :foo:/bin/fo**, } /usr/bin/foo4 { audit allow change_profile /onexec -> :foo:/bin/fo?, } /usr/bin/foo5 { audit allow change_profile /onexec -> :foo:/bin/fo[ab], } /usr/bin/foo6 { audit allow change_profile /onexec -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { audit allow change_profile /onexec -> :fo*:/bin/foo, } /usr/bin/foo8 { audit allow change_profile /onexec -> :fo**:/bin/foo, } /usr/bin/foo9 { audit allow change_profile /onexec -> :fo?:/bin/foo, } /usr/bin/foo10 { audit allow change_profile /onexec -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { audit allow change_profile /onexec -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { audit allow change_profile /onexec -> :fo*:/bin/fo*, } /usr/bin/foo13 { audit allow change_profile /onexec -> :fo**:/bin/fo**, } /usr/bin/foo14 { audit allow change_profile /onexec -> :fo?:/bin/fo?, } /usr/bin/foo15 { audit allow change_profile /onexec -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { audit allow change_profile /onexec -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aa_ok_7.sd0000644000175000017500000000036313502024172023511 0ustar jjjj# #=DESCRIPTION audit allow change_profile /onexec to a hat with quotes #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile /onexec -> "/bin/foo//bar", } /usr/bin/foo2 { audit allow change_profile /onexec -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_bad_1.sd0000644000175000017500000000023213502024172024345 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny owner change_profile @{var} -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_allow_re_ok_2.sd0000644000175000017500000000227713502024172024735 0ustar jjjj# #=DESCRIPTION allow change_profile /onexec to a hat #=EXRESULT PASS # /usr/bin/foo { allow change_profile /onexec -> /bin/foo//bar, } /usr/bin/foo2 { allow change_profile /onexec -> /bin/foo//ba*, } /usr/bin/foo3 { allow change_profile /onexec -> /bin/foo//ba**, } /usr/bin/foo4 { allow change_profile /onexec -> /bin/foo//ba?, } /usr/bin/foo5 { allow change_profile /onexec -> /bin/foo//ba[ab], } /usr/bin/foo6 { allow change_profile /onexec -> /bin/foo//ba[^ab], } /usr/bin/foo7 { allow change_profile /onexec -> /bin/fo*//bar, } /usr/bin/foo8 { allow change_profile /onexec -> /bin/fo**//bar, } /usr/bin/foo9 { allow change_profile /onexec -> /bin/fo?//bar, } /usr/bin/foo10 { allow change_profile /onexec -> /bin/fo[ab]//bar, } /usr/bin/foo11 { allow change_profile /onexec -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { allow change_profile /onexec -> /bin/fo*//ba*, } /usr/bin/foo13 { allow change_profile /onexec -> /bin/fo**//ba**, } /usr/bin/foo14 { allow change_profile /onexec -> /bin/fo?//ba?, } /usr/bin/foo15 { allow change_profile /onexec -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { allow change_profile /onexec -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/o_bad_1.sd0000644000175000017500000000017413502024172022611 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile #=EXRESULT FAIL # /usr/bin/foo { owner change_profile -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_ok_7.sd0000644000175000017500000000037213502024172024225 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} to a hat with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit deny change_profile @{var} -> "/bin/foo//bar", } /usr/bin/foo2 { audit deny change_profile @{var} -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/safe_ok_3.sd0000644000175000017500000000022213502024172023150 0ustar jjjj# #=DESCRIPTION change_profile w/ safe modifier and "safe" target #=EXRESULT PASS # /usr/bin/foo { change_profile safe /usr/bin/bar -> safe, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_allow_re_ok_1.sd0000644000175000017500000000057413502024172024732 0ustar jjjj# #=DESCRIPTION allow change_profile /onexec #=EXRESULT PASS # /usr/bin/foo { allow change_profile /onexec -> /bin/*, } /usr/bin/foo2 { allow change_profile /onexec -> /bin/**, } /usr/bin/foo3 { allow change_profile /onexec -> /bin/?, } /usr/bin/foo4 { allow change_profile /onexec -> /bin/[ab], } /usr/bin/foo5 { allow change_profile /onexec -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aa_ok_3.sd0000644000175000017500000000021613502024172022616 0ustar jjjj# #=DESCRIPTION audit allow change_profile with name space #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ok_5.sd0000644000175000017500000000035113502024172023554 0ustar jjjj# #=DESCRIPTION change_profile @{var} with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { change_profile @{var} -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_ok_4.sd0000644000175000017500000000030313502024172024050 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { audit change_profile @{var} -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_ok_6.sd0000644000175000017500000000030513502024172022623 0ustar jjjj# #=DESCRIPTION audit deny change_profile with quotes #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile -> "/bin/foo", } /usr/bin/foo2 { audit deny change_profile -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_ok_5.sd0000644000175000017500000000034413502024172022625 0ustar jjjj# #=DESCRIPTION audit deny change_profile with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { audit deny change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_re_bad_3.sd0000644000175000017500000000022413502024172024322 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit owner change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_re_ok_6.sd0000644000175000017500000000165013502024172023535 0ustar jjjj# #=DESCRIPTION change_profile /onexec with just res, child profile #=EXRESULT PASS # /usr/bin/foo { change_profile /onexec -> *//ab, } /usr/bin/foo2 { change_profile /onexec -> **//ab, } /usr/bin/foo3 { change_profile /onexec -> ?//ab, } /usr/bin/foo4 { change_profile /onexec -> [ab]//ab, } /usr/bin/foo5 { change_profile /onexec -> [^ab]//ab, } /usr/bin/foo6 { change_profile /onexec -> ab//*, } /usr/bin/foo7 { change_profile /onexec -> ab//**, } /usr/bin/foo8 { change_profile /onexec -> ab//?, } /usr/bin/foo9 { change_profile /onexec -> ab//[ab], } /usr/bin/foo10 { change_profile /onexec -> ab//[^ab], } /usr/bin/foo11 { change_profile /onexec -> *//*, } /usr/bin/foo12 { change_profile /onexec -> **//*, } /usr/bin/foo13 { change_profile /onexec -> ?//*, } /usr/bin/foo14 { change_profile /onexec -> [ab]//*, } /usr/bin/foo15 { change_profile /onexec -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/safe_bad_2.sd0000644000175000017500000000021013502024172023261 0ustar jjjj# #=DESCRIPTION change_profile w/ safe modifier but no exec condition #=EXRESULT FAIL # /usr/bin/foo { change_profile safe -> baz, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_bad_4.sd0000644000175000017500000000026113502024172024002 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" /usr/bin/foo { audit deny owner change_profile /onexec -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_re_ok_8.sd0000644000175000017500000000122613502024172023152 0ustar jjjj# #=DESCRIPTION audit change_profile re with quotes #=EXRESULT PASS # /usr/bin/foo5 { audit change_profile -> "/bin/*", } /usr/bin/foo6 { audit change_profile -> "/bin/**", } /usr/bin/foo7 { audit change_profile -> "/bin/[ab]", } /usr/bin/foo8 { audit change_profile -> "/bin/[^ab]", } /usr/bin/foo10 { audit change_profile -> "/bin/?ab", } /usr/bin/foo11 { audit change_profile -> "/bin/ *", } /usr/bin/foo12 { audit change_profile -> "/bin/ **", } /usr/bin/foo13 { audit change_profile -> "/bin/ [ab]", } /usr/bin/foo14 { audit change_profile -> "/bin/ [^ab]", } /usr/bin/foo15 { audit change_profile -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aa_ok_5.sd0000644000175000017500000000034613502024172022624 0ustar jjjj# #=DESCRIPTION audit allow change_profile with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { audit allow change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_re_ok_5.sd0000644000175000017500000000057113502024172024546 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} with just res #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit change_profile @{var} -> *, } /usr/bin/foo2 { audit change_profile @{var} -> **, } /usr/bin/foo3 { audit change_profile @{var} -> ?, } /usr/bin/foo4 { audit change_profile @{var} -> [ab], } /usr/bin/foo5 { audit change_profile @{var} -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_aao_re_bad_5.sd0000644000175000017500000000023313502024172025176 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit allow owner change_profile @{var} -> *, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_re_ok_3.sd0000644000175000017500000000230413502024172024027 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec with name space #=EXRESULT PASS # /usr/bin/foo { audit change_profile /onexec -> :foo:/bin/foo, } /usr/bin/foo2 { audit change_profile /onexec -> :foo:/bin/fo*, } /usr/bin/foo3 { audit change_profile /onexec -> :foo:/bin/fo**, } /usr/bin/foo4 { audit change_profile /onexec -> :foo:/bin/fo?, } /usr/bin/foo5 { audit change_profile /onexec -> :foo:/bin/fo[ab], } /usr/bin/foo6 { audit change_profile /onexec -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { audit change_profile /onexec -> :fo*:/bin/foo, } /usr/bin/foo8 { audit change_profile /onexec -> :fo**:/bin/foo, } /usr/bin/foo9 { audit change_profile /onexec -> :fo?:/bin/foo, } /usr/bin/foo10 { audit change_profile /onexec -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { audit change_profile /onexec -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { audit change_profile /onexec -> :fo*:/bin/fo*, } /usr/bin/foo13 { audit change_profile /onexec -> :fo**:/bin/fo**, } /usr/bin/foo14 { audit change_profile /onexec -> :fo?:/bin/fo?, } /usr/bin/foo15 { audit change_profile /onexec -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { audit change_profile /onexec -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_re_ok_7.sd0000644000175000017500000000161313502024172023151 0ustar jjjj# #=DESCRIPTION audit change_profile with just re, namespace #=EXRESULT PASS # /usr/bin/foo { audit change_profile -> :ab:*, } /usr/bin/foo2 { audit change_profile -> :ab:**, } /usr/bin/foo3 { audit change_profile -> :ab:?, } /usr/bin/foo4 { audit change_profile -> :ab:[ab], } /usr/bin/foo5 { audit change_profile -> :ab:[^ab], } /usr/bin/foo6 { audit change_profile -> :*:ab, } /usr/bin/foo7 { audit change_profile -> :**:ab, } /usr/bin/foo8 { audit change_profile -> :?:ab, } /usr/bin/foo9 { audit change_profile -> :[ab]:ab, } /usr/bin/foo10 { audit change_profile -> :[^ab]:ab, } /usr/bin/foo11 { audit change_profile -> :*:*, } /usr/bin/foo12 { audit change_profile -> :**:**, } /usr/bin/foo13 { audit change_profile -> :?:?, } /usr/bin/foo14 { audit change_profile -> :[ab]:[ab], } /usr/bin/foo15 { audit change_profile -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_allow_re_ok_3.sd0000644000175000017500000000230013502024172025432 0ustar jjjj# #=DESCRIPTION allow change_profile @{var} with name space #=EXRESULT PASS # @{var}=/test /usr/bin/foo { allow change_profile @{var} -> :foo:/bin/foo, } /usr/bin/foo2 { allow change_profile @{var} -> :foo:/bin/fo*, } /usr/bin/foo3 { allow change_profile @{var} -> :foo:/bin/fo**, } /usr/bin/foo4 { allow change_profile @{var} -> :foo:/bin/fo?, } /usr/bin/foo5 { allow change_profile @{var} -> :foo:/bin/fo[ab], } /usr/bin/foo6 { allow change_profile @{var} -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { allow change_profile @{var} -> :fo*:/bin/foo, } /usr/bin/foo8 { allow change_profile @{var} -> :fo**:/bin/foo, } /usr/bin/foo9 { allow change_profile @{var} -> :fo?:/bin/foo, } /usr/bin/foo10 { allow change_profile @{var} -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { allow change_profile @{var} -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { allow change_profile @{var} -> :fo*:/bin/fo*, } /usr/bin/foo13 { allow change_profile @{var} -> :fo**:/bin/fo**, } /usr/bin/foo14 { allow change_profile @{var} -> :fo?:/bin/fo?, } /usr/bin/foo15 { allow change_profile @{var} -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { allow change_profile @{var} -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_ok_3.sd0000644000175000017500000000020013502024172022451 0ustar jjjj# #=DESCRIPTION deny change_profile with name space #=EXRESULT PASS # /usr/bin/foo { deny change_profile -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_bad_7.sd0000644000175000017500000000023313502024172024004 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit deny owner change_profile /onexec -> "/bin/foo//bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_bad_1.sd0000644000175000017500000000024013502024172024505 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit deny owner change_profile @{var} -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_re_bad_2.sd0000644000175000017500000000023213502024172024670 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { owner change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_re_bad_2.sd0000644000175000017500000000020413502024172024304 0ustar jjjj# #=DESCRIPTION deny audit in wrong order #=EXRESULT FAIL # /usr/bin/foo { deny audit change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_ok_6.sd0000644000175000017500000000033013502024172024052 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit change_profile @{var} -> "/bin/foo", } /usr/bin/foo2 { audit change_profile @{var} -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aa_re_ok_2.sd0000644000175000017500000000244513502024172024175 0ustar jjjj# #=DESCRIPTION audit allow change_profile /onexec to a hat #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile /onexec -> /bin/foo//bar, } /usr/bin/foo2 { audit allow change_profile /onexec -> /bin/foo//ba*, } /usr/bin/foo3 { audit allow change_profile /onexec -> /bin/foo//ba**, } /usr/bin/foo4 { audit allow change_profile /onexec -> /bin/foo//ba?, } /usr/bin/foo5 { audit allow change_profile /onexec -> /bin/foo//ba[ab], } /usr/bin/foo6 { audit allow change_profile /onexec -> /bin/foo//ba[^ab], } /usr/bin/foo7 { audit allow change_profile /onexec -> /bin/fo*//bar, } /usr/bin/foo8 { audit allow change_profile /onexec -> /bin/fo**//bar, } /usr/bin/foo9 { audit allow change_profile /onexec -> /bin/fo?//bar, } /usr/bin/foo10 { audit allow change_profile /onexec -> /bin/fo[ab]//bar, } /usr/bin/foo11 { audit allow change_profile /onexec -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { audit allow change_profile /onexec -> /bin/fo*//ba*, } /usr/bin/foo13 { audit allow change_profile /onexec -> /bin/fo**//ba**, } /usr/bin/foo14 { audit allow change_profile /onexec -> /bin/fo?//ba?, } /usr/bin/foo15 { audit allow change_profile /onexec -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { audit allow change_profile /onexec -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_bad_2.sd0000644000175000017500000000024513502024172024513 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit deny owner change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_bad_6.sd0000644000175000017500000000023413502024172024354 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny owner change_profile @{var} -> "/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_bare_bad_1.sd0000644000175000017500000000022413502024172025500 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit deny owner change_profile @{var}, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_allow_ok_8.sd0000644000175000017500000000036213502024172024757 0ustar jjjj# #=DESCRIPTION allow change_profile @{var} with name space with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo { allow change_profile @{var} -> ":foo:/bin/foo", } /usr/bin/foo2 { allow change_profile @{var} -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aao_re_bad_2.sd0000644000175000017500000000023213502024172024461 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit allow owner change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_re_ok_3.sd0000644000175000017500000000225713502024172024552 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} with name space #=EXRESULT PASS # @{var}=/test /usr/bin/foo { deny change_profile @{var} -> :foo:/bin/foo, } /usr/bin/foo2 { deny change_profile @{var} -> :foo:/bin/fo*, } /usr/bin/foo3 { deny change_profile @{var} -> :foo:/bin/fo**, } /usr/bin/foo4 { deny change_profile @{var} -> :foo:/bin/fo?, } /usr/bin/foo5 { deny change_profile @{var} -> :foo:/bin/fo[ab], } /usr/bin/foo6 { deny change_profile @{var} -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { deny change_profile @{var} -> :fo*:/bin/foo, } /usr/bin/foo8 { deny change_profile @{var} -> :fo**:/bin/foo, } /usr/bin/foo9 { deny change_profile @{var} -> :fo?:/bin/foo, } /usr/bin/foo10 { deny change_profile @{var} -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { deny change_profile @{var} -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { deny change_profile @{var} -> :fo*:/bin/fo*, } /usr/bin/foo13 { deny change_profile @{var} -> :fo**:/bin/fo**, } /usr/bin/foo14 { deny change_profile @{var} -> :fo?:/bin/fo?, } /usr/bin/foo15 { deny change_profile @{var} -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { deny change_profile @{var} -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_re_ok_5.sd0000644000175000017500000000051613502024172023534 0ustar jjjj# #=DESCRIPTION change_profile /onexec with just res #=EXRESULT PASS # /usr/bin/foo { change_profile /onexec -> *, } /usr/bin/foo2 { change_profile /onexec -> **, } /usr/bin/foo3 { change_profile /onexec -> ?, } /usr/bin/foo4 { change_profile /onexec -> [ab], } /usr/bin/foo5 { change_profile /onexec -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aa_re_ok_6.sd0000644000175000017500000000175013502024172023313 0ustar jjjj# #=DESCRIPTION audit allow change_profile with just res, child profile #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile -> *//ab, } /usr/bin/foo2 { audit allow change_profile -> **//ab, } /usr/bin/foo3 { audit allow change_profile -> ?//ab, } /usr/bin/foo4 { audit allow change_profile -> [ab]//ab, } /usr/bin/foo5 { audit allow change_profile -> [^ab]//ab, } /usr/bin/foo6 { audit allow change_profile -> ab//*, } /usr/bin/foo7 { audit allow change_profile -> ab//**, } /usr/bin/foo8 { audit allow change_profile -> ab//?, } /usr/bin/foo9 { audit allow change_profile -> ab//[ab], } /usr/bin/foo10 { audit allow change_profile -> ab//[^ab], } /usr/bin/foo11 { audit allow change_profile -> *//*, } /usr/bin/foo12 { audit allow change_profile -> **//*, } /usr/bin/foo13 { audit allow change_profile -> ?//*, } /usr/bin/foo14 { audit allow change_profile -> [ab]//*, } /usr/bin/foo15 { audit allow change_profile -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_bare_bad_1.sd0000644000175000017500000000020213502024172024622 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { deny owner change_profile /onexec, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aa_re_ok_4.sd0000644000175000017500000000177113502024172024200 0ustar jjjj# #=DESCRIPTION audit allow change_profile /onexec with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { audit allow change_profile /onexec -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { audit allow change_profile /onexec -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { audit allow change_profile /onexec -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { audit allow change_profile /onexec -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { audit allow change_profile /onexec -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { audit allow change_profile /onexec -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { audit allow change_profile /onexec -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { audit allow change_profile /onexec -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { audit allow change_profile /onexec -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { audit allow change_profile /onexec -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { audit allow change_profile /onexec -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_re_bad_7.sd0000644000175000017500000000023713502024172025207 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit deny owner change_profile @{var} -> :ab:*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_allow_re_ok_6.sd0000644000175000017500000000201013502024172024722 0ustar jjjj# #=DESCRIPTION allow change_profile /onexec with just res, child profile #=EXRESULT PASS # /usr/bin/foo { allow change_profile /onexec -> *//ab, } /usr/bin/foo2 { allow change_profile /onexec -> **//ab, } /usr/bin/foo3 { allow change_profile /onexec -> ?//ab, } /usr/bin/foo4 { allow change_profile /onexec -> [ab]//ab, } /usr/bin/foo5 { allow change_profile /onexec -> [^ab]//ab, } /usr/bin/foo6 { allow change_profile /onexec -> ab//*, } /usr/bin/foo7 { allow change_profile /onexec -> ab//**, } /usr/bin/foo8 { allow change_profile /onexec -> ab//?, } /usr/bin/foo9 { allow change_profile /onexec -> ab//[ab], } /usr/bin/foo10 { allow change_profile /onexec -> ab//[^ab], } /usr/bin/foo11 { allow change_profile /onexec -> *//*, } /usr/bin/foo12 { allow change_profile /onexec -> **//*, } /usr/bin/foo13 { allow change_profile /onexec -> ?//*, } /usr/bin/foo14 { allow change_profile /onexec -> [ab]//*, } /usr/bin/foo15 { allow change_profile /onexec -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_ok_4.sd0000644000175000017500000000030113502024172024051 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { deny change_profile @{var} -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ado_bare_bad_1.sd0000644000175000017500000000017313502024172024106 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile #=EXRESULT FAIL # /usr/bin/foo { audit deny owner change_profile, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_ok_2.sd0000644000175000017500000000021113502024172023336 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec to a hat #=EXRESULT PASS # /usr/bin/foo { deny change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_conflict_unsafe1.sd0000644000175000017500000000027113502024172025432 0ustar jjjj# #=DESCRIPTION test for conflict safe and unsafe exec condition #=EXRESULT FAIL # /usr/bin/foo { change_profile /onexec -> /bin/foo, change_profile unsafe /onexec -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/re_ok_1.sd0000644000175000017500000000045013502024172022641 0ustar jjjj# #=DESCRIPTION change_profile #=EXRESULT PASS # /usr/bin/foo { change_profile -> /bin/*, } /usr/bin/foo2 { change_profile -> /bin/**, } /usr/bin/foo3 { change_profile -> /bin/?, } /usr/bin/foo4 { change_profile -> /bin/[ab], } /usr/bin/foo5 { change_profile -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_re_bad_3.sd0000644000175000017500000000020413502024172024305 0ustar jjjj# #=DESCRIPTION deny audit in wrong order #=EXRESULT FAIL # /usr/bin/foo { deny audit change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_ok_8.sd0000644000175000017500000000035713502024172024070 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} with name space with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo { deny change_profile @{var} -> ":foo:/bin/foo", } /usr/bin/foo2 { deny change_profile @{var} -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_re_ok_8.sd0000644000175000017500000000145013502024172024712 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} re with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo5 { audit deny change_profile @{var} -> "/bin/*", } /usr/bin/foo6 { audit deny change_profile @{var} -> "/bin/**", } /usr/bin/foo7 { audit deny change_profile @{var} -> "/bin/[ab]", } /usr/bin/foo8 { audit deny change_profile @{var} -> "/bin/[^ab]", } /usr/bin/foo10 { audit deny change_profile @{var} -> "/bin/?ab", } /usr/bin/foo11 { audit deny change_profile @{var} -> "/bin/ *", } /usr/bin/foo12 { audit deny change_profile @{var} -> "/bin/ **", } /usr/bin/foo13 { audit deny change_profile @{var} -> "/bin/ [ab]", } /usr/bin/foo14 { audit deny change_profile @{var} -> "/bin/ [^ab]", } /usr/bin/foo15 { audit deny change_profile @{var} -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_re_ok_6.sd0000644000175000017500000000212513502024172024710 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} with just res, child profile #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit deny change_profile @{var} -> *//ab, } /usr/bin/foo2 { audit deny change_profile @{var} -> **//ab, } /usr/bin/foo3 { audit deny change_profile @{var} -> ?//ab, } /usr/bin/foo4 { audit deny change_profile @{var} -> [ab]//ab, } /usr/bin/foo5 { audit deny change_profile @{var} -> [^ab]//ab, } /usr/bin/foo6 { audit deny change_profile @{var} -> ab//*, } /usr/bin/foo7 { audit deny change_profile @{var} -> ab//**, } /usr/bin/foo8 { audit deny change_profile @{var} -> ab//?, } /usr/bin/foo9 { audit deny change_profile @{var} -> ab//[ab], } /usr/bin/foo10 { audit deny change_profile @{var} -> ab//[^ab], } /usr/bin/foo11 { audit deny change_profile @{var} -> *//*, } /usr/bin/foo12 { audit deny change_profile @{var} -> **//*, } /usr/bin/foo13 { audit deny change_profile @{var} -> ?//*, } /usr/bin/foo14 { audit deny change_profile @{var} -> [ab]//*, } /usr/bin/foo15 { audit deny change_profile @{var} -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_re_bad_3.sd0000644000175000017500000000023713502024172025042 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny owner change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_bad_3.sd0000644000175000017500000000023213502024172024203 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { owner change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_ok_8.sd0000644000175000017500000000035013502024172023345 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec with name space with quotes #=EXRESULT PASS # /usr/bin/foo { audit change_profile /onexec -> ":foo:/bin/foo", } /usr/bin/foo2 { audit change_profile /onexec -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_aao_re_bad_1.sd0000644000175000017500000000023713502024172025176 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit allow owner change_profile @{var} -> /bin/*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_re_bad_3.sd0000644000175000017500000000023513502024172025022 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny audit change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_ok_7.sd0000644000175000017500000000036013502024172023511 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec to a hat with quotes #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile /onexec -> "/bin/foo//bar", } /usr/bin/foo2 { audit deny change_profile /onexec -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_re_bad_8.sd0000644000175000017500000000021213502024172024674 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo5 { owner change_profile @{var} -> "/bin/*", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_re_bad_5.sd0000644000175000017500000000017113502024172024312 0ustar jjjj# #=DESCRIPTION deny audit in wrong order #=EXRESULT FAIL # /usr/bin/foo { deny audit change_profile /onexec -> *, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_bad_2.sd0000644000175000017500000000023513502024172024333 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny audit change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_allow_ok_3.sd0000644000175000017500000000023513502024172024751 0ustar jjjj# #=DESCRIPTION allow change_profile @{var} with name space #=EXRESULT PASS # @{var}=/test /usr/bin/foo { allow change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_bare_ok_1.sd0000644000175000017500000000017313502024172024476 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile /onexec, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_bad_1.sd0000644000175000017500000000022413502024172023776 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit deny owner change_profile /onexec -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_no_conflict_safe1.sd0000644000175000017500000000033513502024172025564 0ustar jjjj# #=DESCRIPTION 'safe' and unspecified exec condition shouldn't conflict because 'safe' is the default #=EXRESULT PASS # /usr/bin/foo { change_profile safe /onexec -> /bin/foo, change_profile /onexec -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_ok_3.sd0000644000175000017500000000022213502024172023336 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec with name space #=EXRESULT PASS # /usr/bin/foo { audit change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_bad_8.sd0000644000175000017500000000022513502024172023645 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { deny owner change_profile /onexec -> ":foo:/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_ok_1.sd0000644000175000017500000000016713502024172022624 0ustar jjjj# #=DESCRIPTION audit deny change_profile #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_bad_1.sd0000644000175000017500000000021413502024172023616 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # /usr/bin/foo { deny audit change_profile /onexec -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_ok_6.sd0000644000175000017500000000031613502024172023345 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec with quotes #=EXRESULT PASS # /usr/bin/foo { audit change_profile /onexec -> "/bin/foo", } /usr/bin/foo2 { audit change_profile /onexec -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_re_bad_1.sd0000644000175000017500000000022213502024172024462 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit deny owner change_profile /onexec -> /bin/*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aa_ok_4.sd0000644000175000017500000000030413502024172023501 0ustar jjjj# #=DESCRIPTION audit allow change_profile /onexec with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { audit allow change_profile /onexec -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_ok_6.sd0000644000175000017500000000026613502024172022465 0ustar jjjj# #=DESCRIPTION audit change_profile with quotes #=EXRESULT PASS # /usr/bin/foo { audit change_profile -> "/bin/foo", } /usr/bin/foo2 { audit change_profile -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_re_ok_5.sd0000644000175000017500000000056213502024172024035 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec with just res #=EXRESULT PASS # /usr/bin/foo { audit change_profile /onexec -> *, } /usr/bin/foo2 { audit change_profile /onexec -> **, } /usr/bin/foo3 { audit change_profile /onexec -> ?, } /usr/bin/foo4 { audit change_profile /onexec -> [ab], } /usr/bin/foo5 { audit change_profile /onexec -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ok_7.sd0000644000175000017500000000026713502024172022167 0ustar jjjj# #=DESCRIPTION change_profile to a hat with quotes #=EXRESULT PASS # /usr/bin/foo { change_profile -> "/bin/foo//bar", } /usr/bin/foo2 { change_profile -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allow_ok_6.sd0000644000175000017500000000026613502024172023363 0ustar jjjj# #=DESCRIPTION allow change_profile with quotes #=EXRESULT PASS # /usr/bin/foo { allow change_profile -> "/bin/foo", } /usr/bin/foo2 { allow change_profile -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ao_badh_1.sd0000644000175000017500000000020213502024172023112 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile #=EXRESULT FAIL # /usr/bin/foo { audit owner change_profile -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_re_bad_4.sd0000644000175000017500000000032113502024172025032 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" @{var}=/test /usr/bin/foo { audit owner change_profile @{var} -> @{LIBVIRT}-fo*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ok_7.sd0000644000175000017500000000031713502024172023047 0ustar jjjj# #=DESCRIPTION change_profile /onexec to a hat with quotes #=EXRESULT PASS # /usr/bin/foo { change_profile /onexec -> "/bin/foo//bar", } /usr/bin/foo2 { change_profile /onexec -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_re_ok_3.sd0000644000175000017500000000226313502024172024036 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec with name space #=EXRESULT PASS # /usr/bin/foo { deny change_profile /onexec -> :foo:/bin/foo, } /usr/bin/foo2 { deny change_profile /onexec -> :foo:/bin/fo*, } /usr/bin/foo3 { deny change_profile /onexec -> :foo:/bin/fo**, } /usr/bin/foo4 { deny change_profile /onexec -> :foo:/bin/fo?, } /usr/bin/foo5 { deny change_profile /onexec -> :foo:/bin/fo[ab], } /usr/bin/foo6 { deny change_profile /onexec -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { deny change_profile /onexec -> :fo*:/bin/foo, } /usr/bin/foo8 { deny change_profile /onexec -> :fo**:/bin/foo, } /usr/bin/foo9 { deny change_profile /onexec -> :fo?:/bin/foo, } /usr/bin/foo10 { deny change_profile /onexec -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { deny change_profile /onexec -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { deny change_profile /onexec -> :fo*:/bin/fo*, } /usr/bin/foo13 { deny change_profile /onexec -> :fo**:/bin/fo**, } /usr/bin/foo14 { deny change_profile /onexec -> :fo?:/bin/fo?, } /usr/bin/foo15 { deny change_profile /onexec -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { deny change_profile /onexec -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_aao_re_bad_3.sd0000644000175000017500000000024613502024172025200 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit allow owner change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_re_ok_4.sd0000644000175000017500000000150513502024172023151 0ustar jjjj# #=DESCRIPTION deny change_profile with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { deny change_profile -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { deny change_profile -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { deny change_profile -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { deny change_profile -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { deny change_profile -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { deny change_profile -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { deny change_profile -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { deny change_profile -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { deny change_profile -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { deny change_profile -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { deny change_profile -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_re_ok_4.sd0000644000175000017500000000161513502024172023314 0ustar jjjj# #=DESCRIPTION audit deny change_profile with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { audit deny change_profile -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { audit deny change_profile -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { audit deny change_profile -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { audit deny change_profile -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { audit deny change_profile -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { audit deny change_profile -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { audit deny change_profile -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { audit deny change_profile -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { audit deny change_profile -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { audit deny change_profile -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { audit deny change_profile -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_bad_3.sd0000644000175000017500000000024013502024172024343 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit owner change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_bad_8.sd0000644000175000017500000000024213502024172024352 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit owner change_profile @{var} -> ":foo:/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_bad_5.sd0000644000175000017500000000033113502024172023640 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" /usr/bin/foo { deny owner change_profile /onexec -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_re_ok_2.sd0000644000175000017500000000204613502024172023150 0ustar jjjj# #=DESCRIPTION deny change_profile to a hat #=EXRESULT PASS # /usr/bin/foo { deny change_profile -> /bin/foo//bar, } /usr/bin/foo2 { deny change_profile -> /bin/foo//ba*, } /usr/bin/foo3 { deny change_profile -> /bin/foo//ba**, } /usr/bin/foo4 { deny change_profile -> /bin/foo//ba?, } /usr/bin/foo5 { deny change_profile -> /bin/foo//ba[ab], } /usr/bin/foo6 { deny change_profile -> /bin/foo//ba[^ab], } /usr/bin/foo7 { deny change_profile -> /bin/fo*//bar, } /usr/bin/foo8 { deny change_profile -> /bin/fo**//bar, } /usr/bin/foo9 { deny change_profile -> /bin/fo?//bar, } /usr/bin/foo10 { deny change_profile -> /bin/fo[ab]//bar, } /usr/bin/foo11 { deny change_profile -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { deny change_profile -> /bin/fo*//ba*, } /usr/bin/foo13 { deny change_profile -> /bin/fo**//ba**, } /usr/bin/foo14 { deny change_profile -> /bin/fo?//ba?, } /usr/bin/foo15 { deny change_profile -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { deny change_profile -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/re_ok_7.sd0000644000175000017500000000145313502024172022653 0ustar jjjj# #=DESCRIPTION change_profile with just re, namespace #=EXRESULT PASS # /usr/bin/foo { change_profile -> :ab:*, } /usr/bin/foo2 { change_profile -> :ab:**, } /usr/bin/foo3 { change_profile -> :ab:?, } /usr/bin/foo4 { change_profile -> :ab:[ab], } /usr/bin/foo5 { change_profile -> :ab:[^ab], } /usr/bin/foo6 { change_profile -> :*:ab, } /usr/bin/foo7 { change_profile -> :**:ab, } /usr/bin/foo8 { change_profile -> :?:ab, } /usr/bin/foo9 { change_profile -> :[ab]:ab, } /usr/bin/foo10 { change_profile -> :[^ab]:ab, } /usr/bin/foo11 { change_profile -> :*:*, } /usr/bin/foo12 { change_profile -> :**:**, } /usr/bin/foo13 { change_profile -> :?:?, } /usr/bin/foo14 { change_profile -> :[ab]:[ab], } /usr/bin/foo15 { change_profile -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_ok_7.sd0000644000175000017500000000031113502024172022455 0ustar jjjj# #=DESCRIPTION audit change_profile to a hat with quotes #=EXRESULT PASS # /usr/bin/foo { audit change_profile -> "/bin/foo//bar", } /usr/bin/foo2 { audit change_profile -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ok_3.sd0000644000175000017500000000022113502024172023546 0ustar jjjj# #=DESCRIPTION change_profile @{var} with name space #=EXRESULT PASS # @{var}=/test /usr/bin/foo { change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ok_2.sd0000644000175000017500000000021213502024172023545 0ustar jjjj# #=DESCRIPTION change_profile @{var} to a hat #=EXRESULT PASS # @{var}=/test /usr/bin/foo { change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_aao_re_bad_4.sd0000644000175000017500000000032713502024172025201 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" @{var}=/test /usr/bin/foo { audit allow owner change_profile @{var} -> @{LIBVIRT}-fo*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_allow_ok_6.sd0000644000175000017500000000033013502024172024750 0ustar jjjj# #=DESCRIPTION allow change_profile @{var} with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo { allow change_profile @{var} -> "/bin/foo", } /usr/bin/foo2 { allow change_profile @{var} -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_re_ok_4.sd0000644000175000017500000000175613502024172024717 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" @{var}=/test /usr/bin/foo { audit deny change_profile @{var} -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { audit deny change_profile @{var} -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { audit deny change_profile @{var} -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { audit deny change_profile @{var} -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { audit deny change_profile @{var} -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { audit deny change_profile @{var} -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { audit deny change_profile @{var} -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { audit deny change_profile @{var} -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { audit deny change_profile @{var} -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { audit deny change_profile @{var} -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { audit deny change_profile @{var} -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aao_bad_1.sd0000644000175000017500000000022513502024172023774 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit allow owner change_profile /onexec -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_re_bad_4.sd0000644000175000017500000000031313502024172024672 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" @{var}=/test /usr/bin/foo { owner change_profile @{var} -> @{LIBVIRT}-fo*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_ok_3.sd0000644000175000017500000000020213502024172022450 0ustar jjjj# #=DESCRIPTION audit change_profile with name space #=EXRESULT PASS # /usr/bin/foo { audit change_profile -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_ok_8.sd0000644000175000017500000000036213502024172024061 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} with name space with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit change_profile @{var} -> ":foo:/bin/foo", } /usr/bin/foo2 { audit change_profile @{var} -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_re_ok_8.sd0000644000175000017500000000135613502024172024042 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec re with quotes #=EXRESULT PASS # /usr/bin/foo5 { audit change_profile /onexec -> "/bin/*", } /usr/bin/foo6 { audit change_profile /onexec -> "/bin/**", } /usr/bin/foo7 { audit change_profile /onexec -> "/bin/[ab]", } /usr/bin/foo8 { audit change_profile /onexec -> "/bin/[^ab]", } /usr/bin/foo10 { audit change_profile /onexec -> "/bin/?ab", } /usr/bin/foo11 { audit change_profile /onexec -> "/bin/ *", } /usr/bin/foo12 { audit change_profile /onexec -> "/bin/ **", } /usr/bin/foo13 { audit change_profile /onexec -> "/bin/ [ab]", } /usr/bin/foo14 { audit change_profile /onexec -> "/bin/ [^ab]", } /usr/bin/foo15 { audit change_profile /onexec -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aa_re_ok_8.sd0000644000175000017500000000146013502024172024177 0ustar jjjj# #=DESCRIPTION audit allow change_profile /onexec re with quotes #=EXRESULT PASS # /usr/bin/foo5 { audit allow change_profile /onexec -> "/bin/*", } /usr/bin/foo6 { audit allow change_profile /onexec -> "/bin/**", } /usr/bin/foo7 { audit allow change_profile /onexec -> "/bin/[ab]", } /usr/bin/foo8 { audit allow change_profile /onexec -> "/bin/[^ab]", } /usr/bin/foo10 { audit allow change_profile /onexec -> "/bin/?ab", } /usr/bin/foo11 { audit allow change_profile /onexec -> "/bin/ *", } /usr/bin/foo12 { audit allow change_profile /onexec -> "/bin/ **", } /usr/bin/foo13 { audit allow change_profile /onexec -> "/bin/ [ab]", } /usr/bin/foo14 { audit allow change_profile /onexec -> "/bin/ [^ab]", } /usr/bin/foo15 { audit allow change_profile /onexec -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aa_re_ok_7.sd0000644000175000017500000000175313502024172023317 0ustar jjjj# #=DESCRIPTION audit allow change_profile with just re, namespace #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile -> :ab:*, } /usr/bin/foo2 { audit allow change_profile -> :ab:**, } /usr/bin/foo3 { audit allow change_profile -> :ab:?, } /usr/bin/foo4 { audit allow change_profile -> :ab:[ab], } /usr/bin/foo5 { audit allow change_profile -> :ab:[^ab], } /usr/bin/foo6 { audit allow change_profile -> :*:ab, } /usr/bin/foo7 { audit allow change_profile -> :**:ab, } /usr/bin/foo8 { audit allow change_profile -> :?:ab, } /usr/bin/foo9 { audit allow change_profile -> :[ab]:ab, } /usr/bin/foo10 { audit allow change_profile -> :[^ab]:ab, } /usr/bin/foo11 { audit allow change_profile -> :*:*, } /usr/bin/foo12 { audit allow change_profile -> :**:**, } /usr/bin/foo13 { audit allow change_profile -> :?:?, } /usr/bin/foo14 { audit allow change_profile -> :[ab]:[ab], } /usr/bin/foo15 { audit allow change_profile -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_re_ok_2.sd0000644000175000017500000000242013502024172024702 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} to a hat #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit deny change_profile @{var} -> /bin/foo//bar, } /usr/bin/foo2 { audit deny change_profile @{var} -> /bin/foo//ba*, } /usr/bin/foo3 { audit deny change_profile @{var} -> /bin/foo//ba**, } /usr/bin/foo4 { audit deny change_profile @{var} -> /bin/foo//ba?, } /usr/bin/foo5 { audit deny change_profile @{var} -> /bin/foo//ba[ab], } /usr/bin/foo6 { audit deny change_profile @{var} -> /bin/foo//ba[^ab], } /usr/bin/foo7 { audit deny change_profile @{var} -> /bin/fo*//bar, } /usr/bin/foo8 { audit deny change_profile @{var} -> /bin/fo**//bar, } /usr/bin/foo9 { audit deny change_profile @{var} -> /bin/fo?//bar, } /usr/bin/foo10 { audit deny change_profile @{var} -> /bin/fo[ab]//bar, } /usr/bin/foo11 { audit deny change_profile @{var} -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { audit deny change_profile @{var} -> /bin/fo*//ba*, } /usr/bin/foo13 { audit deny change_profile @{var} -> /bin/fo**//ba**, } /usr/bin/foo14 { audit deny change_profile @{var} -> /bin/fo?//ba?, } /usr/bin/foo15 { audit deny change_profile @{var} -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { audit deny change_profile @{var} -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_re_bad_1.sd0000644000175000017500000000022713502024172025021 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny audit change_profile @{var} -> /bin/*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_re_bad_1.sd0000644000175000017500000000021513502024172024320 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit owner change_profile /onexec -> /bin/*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_re_bad_2.sd0000644000175000017500000000023513502024172025021 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny audit change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_bare_bad_1.sd0000644000175000017500000000021113502024172025167 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { owner change_profile @{var}, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aa_ok_8.sd0000644000175000017500000000034213502024172022623 0ustar jjjj# #=DESCRIPTION audit allow change_profile with name space with quotes #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile -> ":foo:/bin/foo", } /usr/bin/foo2 { audit allow change_profile -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_allow_ok_7.sd0000644000175000017500000000034113502024172024242 0ustar jjjj# #=DESCRIPTION allow change_profile /onexec to a hat with quotes #=EXRESULT PASS # /usr/bin/foo { allow change_profile /onexec -> "/bin/foo//bar", } /usr/bin/foo2 { allow change_profile /onexec -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/unsafe_ok_2.sd0000644000175000017500000000017413502024172023520 0ustar jjjj# #=DESCRIPTION change_profile w/ unsafe modifier #=EXRESULT PASS # /usr/bin/foo { change_profile unsafe /usr/bin/bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_bad_5.sd0000644000175000017500000000032713502024172023627 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{LIBVIRT}="libvirt" /usr/bin/foo { deny audit change_profile /onexec -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allow_ok_8.sd0000644000175000017500000000032013502024172023354 0ustar jjjj# #=DESCRIPTION allow change_profile with name space with quotes #=EXRESULT PASS # /usr/bin/foo { allow change_profile -> ":foo:/bin/foo", } /usr/bin/foo2 { allow change_profile -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_ok_1.sd0000644000175000017500000000015513502024172022455 0ustar jjjj# #=DESCRIPTION audit change_profile #=EXRESULT PASS # /usr/bin/foo { audit change_profile -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_ok_1.sd0000644000175000017500000000020713502024172023503 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile /onexec -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_bad_3.sd0000644000175000017500000000023113502024172023776 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit deny owner change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_re_bad_4.sd0000644000175000017500000000032613502024172025203 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" @{var}=/test /usr/bin/foo { audit deny owner change_profile @{var} -> @{LIBVIRT}-fo*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_bad_4.sd0000644000175000017500000000026513502024172024340 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { deny audit change_profile @{var} -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_re_bad_4.sd0000644000175000017500000000031613502024172025023 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" @{var}=/test /usr/bin/foo { deny audit change_profile @{var} -> @{LIBVIRT}-fo*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_re_ok_2.sd0000644000175000017500000000213113502024172023524 0ustar jjjj# #=DESCRIPTION change_profile /onexec to a hat #=EXRESULT PASS # /usr/bin/foo { change_profile /onexec -> /bin/foo//bar, } /usr/bin/foo2 { change_profile /onexec -> /bin/foo//ba*, } /usr/bin/foo3 { change_profile /onexec -> /bin/foo//ba**, } /usr/bin/foo4 { change_profile /onexec -> /bin/foo//ba?, } /usr/bin/foo5 { change_profile /onexec -> /bin/foo//ba[ab], } /usr/bin/foo6 { change_profile /onexec -> /bin/foo//ba[^ab], } /usr/bin/foo7 { change_profile /onexec -> /bin/fo*//bar, } /usr/bin/foo8 { change_profile /onexec -> /bin/fo**//bar, } /usr/bin/foo9 { change_profile /onexec -> /bin/fo?//bar, } /usr/bin/foo10 { change_profile /onexec -> /bin/fo[ab]//bar, } /usr/bin/foo11 { change_profile /onexec -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { change_profile /onexec -> /bin/fo*//ba*, } /usr/bin/foo13 { change_profile /onexec -> /bin/fo**//ba**, } /usr/bin/foo14 { change_profile /onexec -> /bin/fo?//ba?, } /usr/bin/foo15 { change_profile /onexec -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { change_profile /onexec -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_bare_ok_1.sd0000644000175000017500000000016113502024172024327 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec #=EXRESULT PASS # /usr/bin/foo { audit change_profile /onexec, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_ok_2.sd0000644000175000017500000000024013502024172024212 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} to a hat #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit deny change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ok_8.sd0000644000175000017500000000027613502024172022170 0ustar jjjj# #=DESCRIPTION change_profile with name space with quotes #=EXRESULT PASS # /usr/bin/foo { change_profile -> ":foo:/bin/foo", } /usr/bin/foo2 { change_profile -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_bad_4.sd0000644000175000017500000000025413502024172023640 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" /usr/bin/foo { audit owner change_profile /onexec -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allow_ok_1.sd0000644000175000017500000000015513502024172023353 0ustar jjjj# #=DESCRIPTION allow change_profile #=EXRESULT PASS # /usr/bin/foo { allow change_profile -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_bad_8.sd0000644000175000017500000000023313502024172024005 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit deny owner change_profile /onexec -> ":foo:/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_ok_4.sd0000644000175000017500000000024613502024172022464 0ustar jjjj# #=DESCRIPTION deny change_profile with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { deny change_profile -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_re_ok_1.sd0000644000175000017500000000053013502024172023524 0ustar jjjj# #=DESCRIPTION change_profile /onexec #=EXRESULT PASS # /usr/bin/foo { change_profile /onexec -> /bin/*, } /usr/bin/foo2 { change_profile /onexec -> /bin/**, } /usr/bin/foo3 { change_profile /onexec -> /bin/?, } /usr/bin/foo4 { change_profile /onexec -> /bin/[ab], } /usr/bin/foo5 { change_profile /onexec -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_bad_8.sd0000644000175000017500000000022613502024172023643 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit owner change_profile /onexec -> ":foo:/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_re_bad_2.sd0000644000175000017500000000021613502024172024161 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { owner change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_re_bad_3.sd0000644000175000017500000000022313502024172024324 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { deny owner change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_aao_bad_4.sd0000644000175000017500000000027613502024172024516 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { audit allow owner change_profile @{var} -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aa_re_ok_6.sd0000644000175000017500000000215013502024172024172 0ustar jjjj# #=DESCRIPTION audit allow change_profile /onexec with just res, child profile #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile /onexec -> *//ab, } /usr/bin/foo2 { audit allow change_profile /onexec -> **//ab, } /usr/bin/foo3 { audit allow change_profile /onexec -> ?//ab, } /usr/bin/foo4 { audit allow change_profile /onexec -> [ab]//ab, } /usr/bin/foo5 { audit allow change_profile /onexec -> [^ab]//ab, } /usr/bin/foo6 { audit allow change_profile /onexec -> ab//*, } /usr/bin/foo7 { audit allow change_profile /onexec -> ab//**, } /usr/bin/foo8 { audit allow change_profile /onexec -> ab//?, } /usr/bin/foo9 { audit allow change_profile /onexec -> ab//[ab], } /usr/bin/foo10 { audit allow change_profile /onexec -> ab//[^ab], } /usr/bin/foo11 { audit allow change_profile /onexec -> *//*, } /usr/bin/foo12 { audit allow change_profile /onexec -> **//*, } /usr/bin/foo13 { audit allow change_profile /onexec -> ?//*, } /usr/bin/foo14 { audit allow change_profile /onexec -> [ab]//*, } /usr/bin/foo15 { audit allow change_profile /onexec -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_re_ok_4.sd0000644000175000017500000000166113502024172024035 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { audit change_profile /onexec -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { audit change_profile /onexec -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { audit change_profile /onexec -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { audit change_profile /onexec -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { audit change_profile /onexec -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { audit change_profile /onexec -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { audit change_profile /onexec -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { audit change_profile /onexec -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { audit change_profile /onexec -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { audit change_profile /onexec -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { audit change_profile /onexec -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/re_ok_5.sd0000644000175000017500000000043613502024172022651 0ustar jjjj# #=DESCRIPTION change_profile with just res #=EXRESULT PASS # /usr/bin/foo { change_profile -> *, } /usr/bin/foo2 { change_profile -> **, } /usr/bin/foo3 { change_profile -> ?, } /usr/bin/foo4 { change_profile -> [ab], } /usr/bin/foo5 { change_profile -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_re_ok_2.sd0000644000175000017500000000227313502024172024544 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} to a hat #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit change_profile @{var} -> /bin/foo//bar, } /usr/bin/foo2 { audit change_profile @{var} -> /bin/foo//ba*, } /usr/bin/foo3 { audit change_profile @{var} -> /bin/foo//ba**, } /usr/bin/foo4 { audit change_profile @{var} -> /bin/foo//ba?, } /usr/bin/foo5 { audit change_profile @{var} -> /bin/foo//ba[ab], } /usr/bin/foo6 { audit change_profile @{var} -> /bin/foo//ba[^ab], } /usr/bin/foo7 { audit change_profile @{var} -> /bin/fo*//bar, } /usr/bin/foo8 { audit change_profile @{var} -> /bin/fo**//bar, } /usr/bin/foo9 { audit change_profile @{var} -> /bin/fo?//bar, } /usr/bin/foo10 { audit change_profile @{var} -> /bin/fo[ab]//bar, } /usr/bin/foo11 { audit change_profile @{var} -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { audit change_profile @{var} -> /bin/fo*//ba*, } /usr/bin/foo13 { audit change_profile @{var} -> /bin/fo**//ba**, } /usr/bin/foo14 { audit change_profile @{var} -> /bin/fo?//ba?, } /usr/bin/foo15 { audit change_profile @{var} -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { audit change_profile @{var} -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_ok_3.sd0000644000175000017500000000023413502024172023505 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec with name space #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_re_bad_5.sd0000644000175000017500000000022513502024172025036 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit owner change_profile @{var} -> *, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ado_bad_1.sd0000644000175000017500000000020713502024172023113 0ustar jjjj# #=DESCRIPTION owner not allowed on change_profile #=EXRESULT FAIL # /usr/bin/foo { audit deny owner change_profile -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aa_re_ok_1.sd0000644000175000017500000000064013502024172024167 0ustar jjjj# #=DESCRIPTION audit allow change_profile /onexec #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile /onexec -> /bin/*, } /usr/bin/foo2 { audit allow change_profile /onexec -> /bin/**, } /usr/bin/foo3 { audit allow change_profile /onexec -> /bin/?, } /usr/bin/foo4 { audit allow change_profile /onexec -> /bin/[ab], } /usr/bin/foo5 { audit allow change_profile /onexec -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_re_bad_5.sd0000644000175000017500000000021713502024172024676 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { owner change_profile @{var} -> *, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_ok_2.sd0000644000175000017500000000022513502024172023504 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec to a hat #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_re_bad_5.sd0000644000175000017500000000021013502024172024322 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { deny owner change_profile /onexec -> *, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_re_ok_8.sd0000644000175000017500000000144513502024172024205 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec re with quotes #=EXRESULT PASS # /usr/bin/foo5 { audit deny change_profile /onexec -> "/bin/*", } /usr/bin/foo6 { audit deny change_profile /onexec -> "/bin/**", } /usr/bin/foo7 { audit deny change_profile /onexec -> "/bin/[ab]", } /usr/bin/foo8 { audit deny change_profile /onexec -> "/bin/[^ab]", } /usr/bin/foo10 { audit deny change_profile /onexec -> "/bin/?ab", } /usr/bin/foo11 { audit deny change_profile /onexec -> "/bin/ *", } /usr/bin/foo12 { audit deny change_profile /onexec -> "/bin/ **", } /usr/bin/foo13 { audit deny change_profile /onexec -> "/bin/ [ab]", } /usr/bin/foo14 { audit deny change_profile /onexec -> "/bin/ [^ab]", } /usr/bin/foo15 { audit deny change_profile /onexec -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aa_re_ok_5.sd0000644000175000017500000000054613502024172023314 0ustar jjjj# #=DESCRIPTION audit allow change_profile with just res #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile -> *, } /usr/bin/foo2 { audit allow change_profile -> **, } /usr/bin/foo3 { audit allow change_profile -> ?, } /usr/bin/foo4 { audit allow change_profile -> [ab], } /usr/bin/foo5 { audit allow change_profile -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aa_ok_8.sd0000644000175000017500000000037213502024172023512 0ustar jjjj# #=DESCRIPTION audit allow change_profile /onexec with name space with quotes #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile /onexec -> ":foo:/bin/foo", } /usr/bin/foo2 { audit allow change_profile /onexec -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aao_re_bad_4.sd0000644000175000017500000000031313502024172024463 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { audit allow owner change_profile /onexec -> @{LIBVIRT}-fo*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_bad_6.sd0000644000175000017500000000023213502024172024334 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny audit change_profile @{var} -> "/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_bad_5.sd0000644000175000017500000000034613502024172024354 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { audit owner change_profile @{var} -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_re_bad_1.sd0000644000175000017500000000023013502024172025031 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny owner change_profile @{var} -> /bin/*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_re_ok_1.sd0000644000175000017500000000051413502024172023142 0ustar jjjj# #=DESCRIPTION audit change_profile #=EXRESULT PASS # /usr/bin/foo { audit change_profile -> /bin/*, } /usr/bin/foo2 { audit change_profile -> /bin/**, } /usr/bin/foo3 { audit change_profile -> /bin/?, } /usr/bin/foo4 { audit change_profile -> /bin/[ab], } /usr/bin/foo5 { audit change_profile -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_re_ok_1.sd0000644000175000017500000000064113502024172024704 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit deny change_profile @{var} -> /bin/*, } /usr/bin/foo2 { audit deny change_profile @{var} -> /bin/**, } /usr/bin/foo3 { audit deny change_profile @{var} -> /bin/?, } /usr/bin/foo4 { audit deny change_profile @{var} -> /bin/[ab], } /usr/bin/foo5 { audit deny change_profile @{var} -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_ok_8.sd0000644000175000017500000000034513502024172023354 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec with name space with quotes #=EXRESULT PASS # /usr/bin/foo { deny change_profile /onexec -> ":foo:/bin/foo", } /usr/bin/foo2 { deny change_profile /onexec -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allow_re_ok_5.sd0000644000175000017500000000050213502024172024041 0ustar jjjj# #=DESCRIPTION allow change_profile with just res #=EXRESULT PASS # /usr/bin/foo { allow change_profile -> *, } /usr/bin/foo2 { allow change_profile -> **, } /usr/bin/foo3 { allow change_profile -> ?, } /usr/bin/foo4 { allow change_profile -> [ab], } /usr/bin/foo5 { allow change_profile -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_re_bad_4.sd0000644000175000017500000000030513502024172024323 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { audit owner change_profile /onexec -> @{LIBVIRT}-fo*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_re_bad_2.sd0000644000175000017500000000022413502024172024321 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit owner change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_allow_ok_1.sd0000644000175000017500000000017513502024172024241 0ustar jjjj# #=DESCRIPTION allow change_profile /onexec #=EXRESULT PASS # /usr/bin/foo { allow change_profile /onexec -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_ok_8.sd0000644000175000017500000000033713502024172022632 0ustar jjjj# #=DESCRIPTION audit deny change_profile with name space with quotes #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile -> ":foo:/bin/foo", } /usr/bin/foo2 { audit deny change_profile -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_aao_re_bad_8.sd0000644000175000017500000000022613502024172025203 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo5 { audit allow owner change_profile @{var} -> "/bin/*", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_bad_6.sd0000644000175000017500000000022013502024172023636 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { deny owner change_profile /onexec -> "/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_bad_3.sd0000644000175000017500000000024513502024172024514 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit deny owner change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_re_ok_1.sd0000644000175000017500000000053713502024172024244 0ustar jjjj# #=DESCRIPTION change_profile @{var} #=EXRESULT PASS # @{var}=/test /usr/bin/foo { change_profile @{var} -> /bin/*, } /usr/bin/foo2 { change_profile @{var} -> /bin/**, } /usr/bin/foo3 { change_profile @{var} -> /bin/?, } /usr/bin/foo4 { change_profile @{var} -> /bin/[ab], } /usr/bin/foo5 { change_profile @{var} -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_re_ok_2.sd0000644000175000017500000000227713502024172024037 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec to a hat #=EXRESULT PASS # /usr/bin/foo { audit change_profile /onexec -> /bin/foo//bar, } /usr/bin/foo2 { audit change_profile /onexec -> /bin/foo//ba*, } /usr/bin/foo3 { audit change_profile /onexec -> /bin/foo//ba**, } /usr/bin/foo4 { audit change_profile /onexec -> /bin/foo//ba?, } /usr/bin/foo5 { audit change_profile /onexec -> /bin/foo//ba[ab], } /usr/bin/foo6 { audit change_profile /onexec -> /bin/foo//ba[^ab], } /usr/bin/foo7 { audit change_profile /onexec -> /bin/fo*//bar, } /usr/bin/foo8 { audit change_profile /onexec -> /bin/fo**//bar, } /usr/bin/foo9 { audit change_profile /onexec -> /bin/fo?//bar, } /usr/bin/foo10 { audit change_profile /onexec -> /bin/fo[ab]//bar, } /usr/bin/foo11 { audit change_profile /onexec -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { audit change_profile /onexec -> /bin/fo*//ba*, } /usr/bin/foo13 { audit change_profile /onexec -> /bin/fo**//ba**, } /usr/bin/foo14 { audit change_profile /onexec -> /bin/fo?//ba?, } /usr/bin/foo15 { audit change_profile /onexec -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { audit change_profile /onexec -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ok_2.sd0000644000175000017500000000017713502024172023046 0ustar jjjj# #=DESCRIPTION change_profile /onexec to a hat #=EXRESULT PASS # /usr/bin/foo { change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aa_ok_2.sd0000644000175000017500000000020713502024172022615 0ustar jjjj# #=DESCRIPTION audit allow change_profile to a hat #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allow_re_ok_2.sd0000644000175000017500000000206713502024172024046 0ustar jjjj# #=DESCRIPTION allow change_profile to a hat #=EXRESULT PASS # /usr/bin/foo { allow change_profile -> /bin/foo//bar, } /usr/bin/foo2 { allow change_profile -> /bin/foo//ba*, } /usr/bin/foo3 { allow change_profile -> /bin/foo//ba**, } /usr/bin/foo4 { allow change_profile -> /bin/foo//ba?, } /usr/bin/foo5 { allow change_profile -> /bin/foo//ba[ab], } /usr/bin/foo6 { allow change_profile -> /bin/foo//ba[^ab], } /usr/bin/foo7 { allow change_profile -> /bin/fo*//bar, } /usr/bin/foo8 { allow change_profile -> /bin/fo**//bar, } /usr/bin/foo9 { allow change_profile -> /bin/fo?//bar, } /usr/bin/foo10 { allow change_profile -> /bin/fo[ab]//bar, } /usr/bin/foo11 { allow change_profile -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { allow change_profile -> /bin/fo*//ba*, } /usr/bin/foo13 { allow change_profile -> /bin/fo**//ba**, } /usr/bin/foo14 { allow change_profile -> /bin/fo?//ba?, } /usr/bin/foo15 { allow change_profile -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { allow change_profile -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ok_8.sd0000644000175000017500000000034013502024172023555 0ustar jjjj# #=DESCRIPTION change_profile @{var} with name space with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo { change_profile @{var} -> ":foo:/bin/foo", } /usr/bin/foo2 { change_profile @{var} -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/unsafe_bad_1.sd0000644000175000017500000000020513502024172023627 0ustar jjjj# #=DESCRIPTION change_profile w/ unsafe modifier but no exec condition #=EXRESULT FAIL # /usr/bin/foo { change_profile unsafe, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_bare_ok_1.sd0000644000175000017500000000014513502024172024031 0ustar jjjj# #=DESCRIPTION change_profile /onexec #=EXRESULT PASS # /usr/bin/foo { change_profile /onexec, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_re_bad_8.sd0000644000175000017500000000021313502024172024164 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo5 { owner change_profile /onexec -> "/bin/*", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_re_ok_1.sd0000644000175000017500000000050613502024172023146 0ustar jjjj# #=DESCRIPTION deny change_profile #=EXRESULT PASS # /usr/bin/foo { deny change_profile -> /bin/*, } /usr/bin/foo2 { deny change_profile -> /bin/**, } /usr/bin/foo3 { deny change_profile -> /bin/?, } /usr/bin/foo4 { deny change_profile -> /bin/[ab], } /usr/bin/foo5 { deny change_profile -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aao_bad_5.sd0000644000175000017500000000034013502024172023776 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" /usr/bin/foo { audit allow owner change_profile /onexec -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_aao_re_bad_6.sd0000644000175000017500000000023713502024172025203 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit allow owner change_profile @{var} -> *//ab, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_re_ok_1.sd0000644000175000017500000000063213502024172024173 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile /onexec -> /bin/*, } /usr/bin/foo2 { audit deny change_profile /onexec -> /bin/**, } /usr/bin/foo3 { audit deny change_profile /onexec -> /bin/?, } /usr/bin/foo4 { audit deny change_profile /onexec -> /bin/[ab], } /usr/bin/foo5 { audit deny change_profile /onexec -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_re_bad_5.sd0000644000175000017500000000021113502024172024320 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit owner change_profile /onexec -> *, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_allow_re_ok_2.sd0000644000175000017500000000227313502024172025442 0ustar jjjj# #=DESCRIPTION allow change_profile @{var} to a hat #=EXRESULT PASS # @{var}=/test /usr/bin/foo { allow change_profile @{var} -> /bin/foo//bar, } /usr/bin/foo2 { allow change_profile @{var} -> /bin/foo//ba*, } /usr/bin/foo3 { allow change_profile @{var} -> /bin/foo//ba**, } /usr/bin/foo4 { allow change_profile @{var} -> /bin/foo//ba?, } /usr/bin/foo5 { allow change_profile @{var} -> /bin/foo//ba[ab], } /usr/bin/foo6 { allow change_profile @{var} -> /bin/foo//ba[^ab], } /usr/bin/foo7 { allow change_profile @{var} -> /bin/fo*//bar, } /usr/bin/foo8 { allow change_profile @{var} -> /bin/fo**//bar, } /usr/bin/foo9 { allow change_profile @{var} -> /bin/fo?//bar, } /usr/bin/foo10 { allow change_profile @{var} -> /bin/fo[ab]//bar, } /usr/bin/foo11 { allow change_profile @{var} -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { allow change_profile @{var} -> /bin/fo*//ba*, } /usr/bin/foo13 { allow change_profile @{var} -> /bin/fo**//ba**, } /usr/bin/foo14 { allow change_profile @{var} -> /bin/fo?//ba?, } /usr/bin/foo15 { allow change_profile @{var} -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { allow change_profile @{var} -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_re_bad_8.sd0000644000175000017500000000020113502024172024307 0ustar jjjj# #=DESCRIPTION deny audit in wrong order #=EXRESULT FAIL # /usr/bin/foo5 { deny audit change_profile /onexec -> "/bin/*", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_bad_3.sd0000644000175000017500000000023713502024172024354 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny owner change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_bad_5.sd0000644000175000017500000000034013502024172024205 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { owner change_profile @{var} -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ao_bare_bad_1.sd0000644000175000017500000000020313502024172024620 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit owner change_profile /onexec, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ok_6.sd0000644000175000017500000000024413502024172022161 0ustar jjjj# #=DESCRIPTION change_profile with quotes #=EXRESULT PASS # /usr/bin/foo { change_profile -> "/bin/foo", } /usr/bin/foo2 { change_profile -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_bare_bad_1.sd0000644000175000017500000000017713502024172025330 0ustar jjjj# #=DESCRIPTION deny audit in wrong order #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny audit change_profile @{var}, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_re_ok_4.sd0000644000175000017500000000164513502024172024042 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { deny change_profile /onexec -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { deny change_profile /onexec -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { deny change_profile /onexec -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { deny change_profile /onexec -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { deny change_profile /onexec -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { deny change_profile /onexec -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { deny change_profile /onexec -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { deny change_profile /onexec -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { deny change_profile /onexec -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { deny change_profile /onexec -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { deny change_profile /onexec -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_re_bad_3.sd0000644000175000017500000000023213502024172024671 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { owner change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_re_ok_7.sd0000644000175000017500000000201313502024172024030 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec with just re, namespace #=EXRESULT PASS # /usr/bin/foo { audit change_profile /onexec -> :ab:*, } /usr/bin/foo2 { audit change_profile /onexec -> :ab:**, } /usr/bin/foo3 { audit change_profile /onexec -> :ab:?, } /usr/bin/foo4 { audit change_profile /onexec -> :ab:[ab], } /usr/bin/foo5 { audit change_profile /onexec -> :ab:[^ab], } /usr/bin/foo6 { audit change_profile /onexec -> :*:ab, } /usr/bin/foo7 { audit change_profile /onexec -> :**:ab, } /usr/bin/foo8 { audit change_profile /onexec -> :?:ab, } /usr/bin/foo9 { audit change_profile /onexec -> :[ab]:ab, } /usr/bin/foo10 { audit change_profile /onexec -> :[^ab]:ab, } /usr/bin/foo11 { audit change_profile /onexec -> :*:*, } /usr/bin/foo12 { audit change_profile /onexec -> :**:**, } /usr/bin/foo13 { audit change_profile /onexec -> :?:?, } /usr/bin/foo14 { audit change_profile /onexec -> :[ab]:[ab], } /usr/bin/foo15 { audit change_profile /onexec -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_re_ok_5.sd0000644000175000017500000000056313502024172024552 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} with just res #=EXRESULT PASS # @{var}=/test /usr/bin/foo { deny change_profile @{var} -> *, } /usr/bin/foo2 { deny change_profile @{var} -> **, } /usr/bin/foo3 { deny change_profile @{var} -> ?, } /usr/bin/foo4 { deny change_profile @{var} -> [ab], } /usr/bin/foo5 { deny change_profile @{var} -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_allow_ok_4.sd0000644000175000017500000000027013502024172024240 0ustar jjjj# #=DESCRIPTION allow change_profile /onexec with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { allow change_profile /onexec -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_re_ok_6.sd0000644000175000017500000000213013502024172024173 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec with just res, child profile #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile /onexec -> *//ab, } /usr/bin/foo2 { audit deny change_profile /onexec -> **//ab, } /usr/bin/foo3 { audit deny change_profile /onexec -> ?//ab, } /usr/bin/foo4 { audit deny change_profile /onexec -> [ab]//ab, } /usr/bin/foo5 { audit deny change_profile /onexec -> [^ab]//ab, } /usr/bin/foo6 { audit deny change_profile /onexec -> ab//*, } /usr/bin/foo7 { audit deny change_profile /onexec -> ab//**, } /usr/bin/foo8 { audit deny change_profile /onexec -> ab//?, } /usr/bin/foo9 { audit deny change_profile /onexec -> ab//[ab], } /usr/bin/foo10 { audit deny change_profile /onexec -> ab//[^ab], } /usr/bin/foo11 { audit deny change_profile /onexec -> *//*, } /usr/bin/foo12 { audit deny change_profile /onexec -> **//*, } /usr/bin/foo13 { audit deny change_profile /onexec -> ?//*, } /usr/bin/foo14 { audit deny change_profile /onexec -> [ab]//*, } /usr/bin/foo15 { audit deny change_profile /onexec -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_bad_8.sd0000644000175000017500000000023713502024172024343 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny audit change_profile @{var} -> ":foo:/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_bad_4.sd0000644000175000017500000000025113502024172023622 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{LIBVIRT}="libvirt" /usr/bin/foo { deny audit change_profile /onexec -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_re_ok_7.sd0000644000175000017500000000213013502024172024705 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} with just re, namespace #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit deny change_profile @{var} -> :ab:*, } /usr/bin/foo2 { audit deny change_profile @{var} -> :ab:**, } /usr/bin/foo3 { audit deny change_profile @{var} -> :ab:?, } /usr/bin/foo4 { audit deny change_profile @{var} -> :ab:[ab], } /usr/bin/foo5 { audit deny change_profile @{var} -> :ab:[^ab], } /usr/bin/foo6 { audit deny change_profile @{var} -> :*:ab, } /usr/bin/foo7 { audit deny change_profile @{var} -> :**:ab, } /usr/bin/foo8 { audit deny change_profile @{var} -> :?:ab, } /usr/bin/foo9 { audit deny change_profile @{var} -> :[ab]:ab, } /usr/bin/foo10 { audit deny change_profile @{var} -> :[^ab]:ab, } /usr/bin/foo11 { audit deny change_profile @{var} -> :*:*, } /usr/bin/foo12 { audit deny change_profile @{var} -> :**:**, } /usr/bin/foo13 { audit deny change_profile @{var} -> :?:?, } /usr/bin/foo14 { audit deny change_profile @{var} -> :[ab]:[ab], } /usr/bin/foo15 { audit deny change_profile @{var} -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_ok_1.sd0000644000175000017500000000017513502024172023343 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec #=EXRESULT PASS # /usr/bin/foo { audit change_profile /onexec -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_bare_ok_1.sd0000644000175000017500000000016013502024172024537 0ustar jjjj# #=DESCRIPTION change_profile @{var} #=EXRESULT PASS # @{var}=/test /usr/bin/foo { change_profile @{var}, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_allow_re_ok_3.sd0000644000175000017500000000230413502024172024725 0ustar jjjj# #=DESCRIPTION allow change_profile /onexec with name space #=EXRESULT PASS # /usr/bin/foo { allow change_profile /onexec -> :foo:/bin/foo, } /usr/bin/foo2 { allow change_profile /onexec -> :foo:/bin/fo*, } /usr/bin/foo3 { allow change_profile /onexec -> :foo:/bin/fo**, } /usr/bin/foo4 { allow change_profile /onexec -> :foo:/bin/fo?, } /usr/bin/foo5 { allow change_profile /onexec -> :foo:/bin/fo[ab], } /usr/bin/foo6 { allow change_profile /onexec -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { allow change_profile /onexec -> :fo*:/bin/foo, } /usr/bin/foo8 { allow change_profile /onexec -> :fo**:/bin/foo, } /usr/bin/foo9 { allow change_profile /onexec -> :fo?:/bin/foo, } /usr/bin/foo10 { allow change_profile /onexec -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { allow change_profile /onexec -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { allow change_profile /onexec -> :fo*:/bin/fo*, } /usr/bin/foo13 { allow change_profile /onexec -> :fo**:/bin/fo**, } /usr/bin/foo14 { allow change_profile /onexec -> :fo?:/bin/fo?, } /usr/bin/foo15 { allow change_profile /onexec -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { allow change_profile /onexec -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_re_bad_4.sd0000644000175000017500000000031213502024172024465 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { audit deny owner change_profile /onexec -> @{LIBVIRT}-fo*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_re_ok_7.sd0000644000175000017500000000177013502024172024555 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} with just re, namespace #=EXRESULT PASS # @{var}=/test /usr/bin/foo { deny change_profile @{var} -> :ab:*, } /usr/bin/foo2 { deny change_profile @{var} -> :ab:**, } /usr/bin/foo3 { deny change_profile @{var} -> :ab:?, } /usr/bin/foo4 { deny change_profile @{var} -> :ab:[ab], } /usr/bin/foo5 { deny change_profile @{var} -> :ab:[^ab], } /usr/bin/foo6 { deny change_profile @{var} -> :*:ab, } /usr/bin/foo7 { deny change_profile @{var} -> :**:ab, } /usr/bin/foo8 { deny change_profile @{var} -> :?:ab, } /usr/bin/foo9 { deny change_profile @{var} -> :[ab]:ab, } /usr/bin/foo10 { deny change_profile @{var} -> :[^ab]:ab, } /usr/bin/foo11 { deny change_profile @{var} -> :*:*, } /usr/bin/foo12 { deny change_profile @{var} -> :**:**, } /usr/bin/foo13 { deny change_profile @{var} -> :?:?, } /usr/bin/foo14 { deny change_profile @{var} -> :[ab]:[ab], } /usr/bin/foo15 { deny change_profile @{var} -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_bad_6.sd0000644000175000017500000000021313502024172023474 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { owner change_profile /onexec -> "/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_ok_1.sd0000644000175000017500000000022213502024172024211 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit deny change_profile @{var} -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_bad_1.sd0000644000175000017500000000023013502024172024325 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny audit change_profile @{var} -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_bad_4.sd0000644000175000017500000000026213502024172024207 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { owner change_profile @{var} -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_re_bad_6.sd0000644000175000017500000000017513502024172024317 0ustar jjjj# #=DESCRIPTION deny audit in wrong order #=EXRESULT FAIL # /usr/bin/foo { deny audit change_profile /onexec -> *//ab, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_re_bad_6.sd0000644000175000017500000000023613502024172025205 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit deny owner change_profile @{var} -> *//ab, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_re_bad_3.sd0000644000175000017500000000024013502024172025031 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit owner change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ok_1.sd0000644000175000017500000000017413502024172023553 0ustar jjjj# #=DESCRIPTION change_profile @{var} #=EXRESULT PASS # @{var}=/test /usr/bin/foo { change_profile @{var} -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_bad_1.sd0000644000175000017500000000021113502024172023465 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { owner change_profile /onexec -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_re_bad_2.sd0000644000175000017500000000023713502024172025041 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny owner change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_re_ok_4.sd0000644000175000017500000000152113502024172023144 0ustar jjjj# #=DESCRIPTION audit change_profile with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { audit change_profile -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { audit change_profile -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { audit change_profile -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { audit change_profile -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { audit change_profile -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { audit change_profile -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { audit change_profile -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { audit change_profile -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { audit change_profile -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { audit change_profile -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { audit change_profile -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_re_ok_8.sd0000644000175000017500000000131513502024172023315 0ustar jjjj# #=DESCRIPTION audit deny change_profile re with quotes #=EXRESULT PASS # /usr/bin/foo5 { audit deny change_profile -> "/bin/*", } /usr/bin/foo6 { audit deny change_profile -> "/bin/**", } /usr/bin/foo7 { audit deny change_profile -> "/bin/[ab]", } /usr/bin/foo8 { audit deny change_profile -> "/bin/[^ab]", } /usr/bin/foo10 { audit deny change_profile -> "/bin/?ab", } /usr/bin/foo11 { audit deny change_profile -> "/bin/ *", } /usr/bin/foo12 { audit deny change_profile -> "/bin/ **", } /usr/bin/foo13 { audit deny change_profile -> "/bin/ [ab]", } /usr/bin/foo14 { audit deny change_profile -> "/bin/ [^ab]", } /usr/bin/foo15 { audit deny change_profile -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_bare_ok_1.sd0000644000175000017500000000015313502024172023610 0ustar jjjj# #=DESCRIPTION audit deny change_profile #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allow_ok_5.sd0000644000175000017500000000033213502024172023354 0ustar jjjj# #=DESCRIPTION allow change_profile with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { allow change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_re_ok_6.sd0000644000175000017500000000173013502024172023314 0ustar jjjj# #=DESCRIPTION audit deny change_profile with just res, child profile #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile -> *//ab, } /usr/bin/foo2 { audit deny change_profile -> **//ab, } /usr/bin/foo3 { audit deny change_profile -> ?//ab, } /usr/bin/foo4 { audit deny change_profile -> [ab]//ab, } /usr/bin/foo5 { audit deny change_profile -> [^ab]//ab, } /usr/bin/foo6 { audit deny change_profile -> ab//*, } /usr/bin/foo7 { audit deny change_profile -> ab//**, } /usr/bin/foo8 { audit deny change_profile -> ab//?, } /usr/bin/foo9 { audit deny change_profile -> ab//[ab], } /usr/bin/foo10 { audit deny change_profile -> ab//[^ab], } /usr/bin/foo11 { audit deny change_profile -> *//*, } /usr/bin/foo12 { audit deny change_profile -> **//*, } /usr/bin/foo13 { audit deny change_profile -> ?//*, } /usr/bin/foo14 { audit deny change_profile -> [ab]//*, } /usr/bin/foo15 { audit deny change_profile -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aao_bad_6.sd0000644000175000017500000000023013502024172023775 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit allow owner change_profile /onexec -> "/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_ok_3.sd0000644000175000017500000000022013502024172023337 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec with name space #=EXRESULT PASS # /usr/bin/foo { deny change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_ok_8.sd0000644000175000017500000000031513502024172022465 0ustar jjjj# #=DESCRIPTION deny change_profile with name space with quotes #=EXRESULT PASS # /usr/bin/foo { deny change_profile -> ":foo:/bin/foo", } /usr/bin/foo2 { deny change_profile -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_ok_7.sd0000644000175000017500000000030613502024172022464 0ustar jjjj# #=DESCRIPTION deny change_profile to a hat with quotes #=EXRESULT PASS # /usr/bin/foo { deny change_profile -> "/bin/foo//bar", } /usr/bin/foo2 { deny change_profile -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_re_bad_5.sd0000644000175000017500000000020313502024172024160 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { owner change_profile /onexec -> *, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_re_bad_4.sd0000644000175000017500000000030413502024172024325 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { deny owner change_profile /onexec -> @{LIBVIRT}-fo*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_re_ok_2.sd0000644000175000017500000000225213502024172024544 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} to a hat #=EXRESULT PASS # @{var}=/test /usr/bin/foo { deny change_profile @{var} -> /bin/foo//bar, } /usr/bin/foo2 { deny change_profile @{var} -> /bin/foo//ba*, } /usr/bin/foo3 { deny change_profile @{var} -> /bin/foo//ba**, } /usr/bin/foo4 { deny change_profile @{var} -> /bin/foo//ba?, } /usr/bin/foo5 { deny change_profile @{var} -> /bin/foo//ba[ab], } /usr/bin/foo6 { deny change_profile @{var} -> /bin/foo//ba[^ab], } /usr/bin/foo7 { deny change_profile @{var} -> /bin/fo*//bar, } /usr/bin/foo8 { deny change_profile @{var} -> /bin/fo**//bar, } /usr/bin/foo9 { deny change_profile @{var} -> /bin/fo?//bar, } /usr/bin/foo10 { deny change_profile @{var} -> /bin/fo[ab]//bar, } /usr/bin/foo11 { deny change_profile @{var} -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { deny change_profile @{var} -> /bin/fo*//ba*, } /usr/bin/foo13 { deny change_profile @{var} -> /bin/fo**//ba**, } /usr/bin/foo14 { deny change_profile @{var} -> /bin/fo?//ba?, } /usr/bin/foo15 { deny change_profile @{var} -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { deny change_profile @{var} -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_aao_bad_1.sd0000644000175000017500000000024313502024172024505 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit allow owner change_profile @{var} -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_allow_ok_6.sd0000644000175000017500000000031613502024172024243 0ustar jjjj# #=DESCRIPTION allow change_profile /onexec with quotes #=EXRESULT PASS # /usr/bin/foo { allow change_profile /onexec -> "/bin/foo", } /usr/bin/foo2 { allow change_profile /onexec -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_ok_7.sd0000644000175000017500000000035013502024172024060 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} to a hat with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo { deny change_profile @{var} -> "/bin/foo//bar", } /usr/bin/foo2 { deny change_profile @{var} -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_bare_ok_1.sd0000644000175000017500000000014113502024172023441 0ustar jjjj# #=DESCRIPTION audit change_profile #=EXRESULT PASS # /usr/bin/foo { audit change_profile, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_re_bad_6.sd0000644000175000017500000000021413502024172024327 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { deny owner change_profile /onexec -> *//ab, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_ok_1.sd0000644000175000017500000000020613502024172024052 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} #=EXRESULT PASS # @{var}=/test /usr/bin/foo { deny change_profile @{var} -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_re_bad_7.sd0000644000175000017500000000022413502024172024676 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { owner change_profile @{var} -> :ab:*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_bad_8.sd0000644000175000017500000000022313502024172023625 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # /usr/bin/foo { deny audit change_profile /onexec -> ":foo:/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/bad_outside_1.sd0000644000175000017500000000015113502024172024022 0ustar jjjj# #=DESCRIPTION change_profile rule outside of a profile #=EXRESULT FAIL # change_profile -> /bin/foo, apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_ok_5.sd0000644000175000017500000000035213502024172023344 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { audit change_profile /onexec -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allow_re_ok_6.sd0000644000175000017500000000161013502024172024043 0ustar jjjj# #=DESCRIPTION allow change_profile with just res, child profile #=EXRESULT PASS # /usr/bin/foo { allow change_profile -> *//ab, } /usr/bin/foo2 { allow change_profile -> **//ab, } /usr/bin/foo3 { allow change_profile -> ?//ab, } /usr/bin/foo4 { allow change_profile -> [ab]//ab, } /usr/bin/foo5 { allow change_profile -> [^ab]//ab, } /usr/bin/foo6 { allow change_profile -> ab//*, } /usr/bin/foo7 { allow change_profile -> ab//**, } /usr/bin/foo8 { allow change_profile -> ab//?, } /usr/bin/foo9 { allow change_profile -> ab//[ab], } /usr/bin/foo10 { allow change_profile -> ab//[^ab], } /usr/bin/foo11 { allow change_profile -> *//*, } /usr/bin/foo12 { allow change_profile -> **//*, } /usr/bin/foo13 { allow change_profile -> ?//*, } /usr/bin/foo14 { allow change_profile -> [ab]//*, } /usr/bin/foo15 { allow change_profile -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_re_ok_3.sd0000644000175000017500000000207413502024172023147 0ustar jjjj# #=DESCRIPTION audit change_profile with name space #=EXRESULT PASS # /usr/bin/foo { audit change_profile -> :foo:/bin/foo, } /usr/bin/foo2 { audit change_profile -> :foo:/bin/fo*, } /usr/bin/foo3 { audit change_profile -> :foo:/bin/fo**, } /usr/bin/foo4 { audit change_profile -> :foo:/bin/fo?, } /usr/bin/foo5 { audit change_profile -> :foo:/bin/fo[ab], } /usr/bin/foo6 { audit change_profile -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { audit change_profile -> :fo*:/bin/foo, } /usr/bin/foo8 { audit change_profile -> :fo**:/bin/foo, } /usr/bin/foo9 { audit change_profile -> :fo?:/bin/foo, } /usr/bin/foo10 { audit change_profile -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { audit change_profile -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { audit change_profile -> :fo*:/bin/fo*, } /usr/bin/foo13 { audit change_profile -> :fo**:/bin/fo**, } /usr/bin/foo14 { audit change_profile -> :fo?:/bin/fo?, } /usr/bin/foo15 { audit change_profile -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { audit change_profile -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_bad_5.sd0000644000175000017500000000033713502024172024007 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" /usr/bin/foo { audit deny owner change_profile /onexec -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_conflict_unsafe2.sd0000644000175000017500000000027613502024172025440 0ustar jjjj# #=DESCRIPTION test for conflict safe and unsafe exec condition #=EXRESULT FAIL # /usr/bin/foo { change_profile safe /onexec -> /bin/foo, change_profile unsafe /onexec -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_re_ok_6.sd0000644000175000017500000000157013502024172023155 0ustar jjjj# #=DESCRIPTION deny change_profile with just res, child profile #=EXRESULT PASS # /usr/bin/foo { deny change_profile -> *//ab, } /usr/bin/foo2 { deny change_profile -> **//ab, } /usr/bin/foo3 { deny change_profile -> ?//ab, } /usr/bin/foo4 { deny change_profile -> [ab]//ab, } /usr/bin/foo5 { deny change_profile -> [^ab]//ab, } /usr/bin/foo6 { deny change_profile -> ab//*, } /usr/bin/foo7 { deny change_profile -> ab//**, } /usr/bin/foo8 { deny change_profile -> ab//?, } /usr/bin/foo9 { deny change_profile -> ab//[ab], } /usr/bin/foo10 { deny change_profile -> ab//[^ab], } /usr/bin/foo11 { deny change_profile -> *//*, } /usr/bin/foo12 { deny change_profile -> **//*, } /usr/bin/foo13 { deny change_profile -> ?//*, } /usr/bin/foo14 { deny change_profile -> [ab]//*, } /usr/bin/foo15 { deny change_profile -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_bad_2.sd0000644000175000017500000000023213502024172024202 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { owner change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_allow_ok_1.sd0000644000175000017500000000021013502024172024740 0ustar jjjj# #=DESCRIPTION allow change_profile @{var} #=EXRESULT PASS # @{var}=/test /usr/bin/foo { allow change_profile @{var} -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_re_bad_8.sd0000644000175000017500000000022513502024172025205 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo5 { audit deny owner change_profile @{var} -> "/bin/*", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_re_ok_5.sd0000644000175000017500000000050213502024172023143 0ustar jjjj# #=DESCRIPTION audit change_profile with just res #=EXRESULT PASS # /usr/bin/foo { audit change_profile -> *, } /usr/bin/foo2 { audit change_profile -> **, } /usr/bin/foo3 { audit change_profile -> ?, } /usr/bin/foo4 { audit change_profile -> [ab], } /usr/bin/foo5 { audit change_profile -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_re_ok_8.sd0000644000175000017500000000121313502024172023151 0ustar jjjj# #=DESCRIPTION deny change_profile re with quotes #=EXRESULT PASS # /usr/bin/foo5 { deny change_profile -> "/bin/*", } /usr/bin/foo6 { deny change_profile -> "/bin/**", } /usr/bin/foo7 { deny change_profile -> "/bin/[ab]", } /usr/bin/foo8 { deny change_profile -> "/bin/[^ab]", } /usr/bin/foo10 { deny change_profile -> "/bin/?ab", } /usr/bin/foo11 { deny change_profile -> "/bin/ *", } /usr/bin/foo12 { deny change_profile -> "/bin/ **", } /usr/bin/foo13 { deny change_profile -> "/bin/ [ab]", } /usr/bin/foo14 { deny change_profile -> "/bin/ [^ab]", } /usr/bin/foo15 { deny change_profile -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_bad_2.sd0000644000175000017500000000021613502024172023473 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { owner change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ok_7.sd0000644000175000017500000000033113502024172023554 0ustar jjjj# #=DESCRIPTION change_profile @{var} to a hat with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo { change_profile @{var} -> "/bin/foo//bar", } /usr/bin/foo2 { change_profile @{var} -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_re_ok_1.sd0000644000175000017500000000057413502024172024034 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec #=EXRESULT PASS # /usr/bin/foo { audit change_profile /onexec -> /bin/*, } /usr/bin/foo2 { audit change_profile /onexec -> /bin/**, } /usr/bin/foo3 { audit change_profile /onexec -> /bin/?, } /usr/bin/foo4 { audit change_profile /onexec -> /bin/[ab], } /usr/bin/foo5 { audit change_profile /onexec -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_re_bad_4.sd0000644000175000017500000000027713502024172024172 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { owner change_profile /onexec -> @{LIBVIRT}-fo*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_re_bad_7.sd0000644000175000017500000000022713502024172025027 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny audit change_profile @{var} -> :ab:*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_bad_8.sd0000644000175000017500000000024713502024172024523 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit deny owner change_profile @{var} -> ":foo:/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aa_re_ok_4.sd0000644000175000017500000000163113502024172023307 0ustar jjjj# #=DESCRIPTION audit allow change_profile with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { audit allow change_profile -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { audit allow change_profile -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { audit allow change_profile -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { audit allow change_profile -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { audit allow change_profile -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { audit allow change_profile -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { audit allow change_profile -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { audit allow change_profile -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { audit allow change_profile -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { audit allow change_profile -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { audit allow change_profile -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aa_ok_1.sd0000644000175000017500000000021113502024172023473 0ustar jjjj# #=DESCRIPTION audit allow change_profile /onexec #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile /onexec -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_re_bad_1.sd0000644000175000017500000000017513502024172024312 0ustar jjjj# #=DESCRIPTION deny audit in wrong order #=EXRESULT FAIL # /usr/bin/foo { deny audit change_profile /onexec -> /bin/*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_bad_8.sd0000644000175000017500000000024113502024172024354 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny owner change_profile @{var} -> ":foo:/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_allow_ok_2.sd0000644000175000017500000000022613502024172024750 0ustar jjjj# #=DESCRIPTION allow change_profile @{var} to a hat #=EXRESULT PASS # @{var}=/test /usr/bin/foo { allow change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_re_bad_7.sd0000644000175000017500000000023213502024172025036 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit owner change_profile @{var} -> :ab:*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_re_ok_4.sd0000644000175000017500000000155113502024172023533 0ustar jjjj# #=DESCRIPTION change_profile /onexec with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { change_profile /onexec -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { change_profile /onexec -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { change_profile /onexec -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { change_profile /onexec -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { change_profile /onexec -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { change_profile /onexec -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { change_profile /onexec -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { change_profile /onexec -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { change_profile /onexec -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { change_profile /onexec -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { change_profile /onexec -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ok_4.sd0000644000175000017500000000025413502024172023044 0ustar jjjj# #=DESCRIPTION change_profile /onexec with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { change_profile /onexec -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ok_3.sd0000644000175000017500000000020613502024172023040 0ustar jjjj# #=DESCRIPTION change_profile /onexec with name space #=EXRESULT PASS # /usr/bin/foo { change_profile /onexec -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/safe_ok_2.sd0000644000175000017500000000017013502024172023151 0ustar jjjj# #=DESCRIPTION change_profile w/ safe modifier #=EXRESULT PASS # /usr/bin/foo { change_profile safe /usr/bin/bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_allow_ok_8.sd0000644000175000017500000000035013502024172024243 0ustar jjjj# #=DESCRIPTION allow change_profile /onexec with name space with quotes #=EXRESULT PASS # /usr/bin/foo { allow change_profile /onexec -> ":foo:/bin/foo", } /usr/bin/foo2 { allow change_profile /onexec -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aao_re_bad_6.sd0000644000175000017500000000022313502024172024465 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit allow owner change_profile /onexec -> *//ab, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_ok_6.sd0000644000175000017500000000026313502024172022465 0ustar jjjj# #=DESCRIPTION deny change_profile with quotes #=EXRESULT PASS # /usr/bin/foo { deny change_profile -> "/bin/foo", } /usr/bin/foo2 { deny change_profile -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_allow_re_ok_4.sd0000644000175000017500000000166213502024172025445 0ustar jjjj# #=DESCRIPTION allow change_profile @{var} with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" @{var}=/test /usr/bin/foo { allow change_profile @{var} -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { allow change_profile @{var} -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { allow change_profile @{var} -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { allow change_profile @{var} -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { allow change_profile @{var} -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { allow change_profile @{var} -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { allow change_profile @{var} -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { allow change_profile @{var} -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { allow change_profile @{var} -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { allow change_profile @{var} -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { allow change_profile @{var} -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_re_bad_3.sd0000644000175000017500000000024513502024172025202 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit deny owner change_profile @{var} -> :foo:/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ok_6.sd0000644000175000017500000000030613502024172023555 0ustar jjjj# #=DESCRIPTION change_profile @{var} with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo { change_profile @{var} -> "/bin/foo", } /usr/bin/foo2 { change_profile @{var} -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_re_ok_8.sd0000644000175000017500000000125413502024172023537 0ustar jjjj# #=DESCRIPTION change_profile /onexec re with quotes #=EXRESULT PASS # /usr/bin/foo5 { change_profile /onexec -> "/bin/*", } /usr/bin/foo6 { change_profile /onexec -> "/bin/**", } /usr/bin/foo7 { change_profile /onexec -> "/bin/[ab]", } /usr/bin/foo8 { change_profile /onexec -> "/bin/[^ab]", } /usr/bin/foo10 { change_profile /onexec -> "/bin/?ab", } /usr/bin/foo11 { change_profile /onexec -> "/bin/ *", } /usr/bin/foo12 { change_profile /onexec -> "/bin/ **", } /usr/bin/foo13 { change_profile /onexec -> "/bin/ [ab]", } /usr/bin/foo14 { change_profile /onexec -> "/bin/ [^ab]", } /usr/bin/foo15 { change_profile /onexec -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_ok_6.sd0000644000175000017500000000034713502024172024226 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit deny change_profile @{var} -> "/bin/foo", } /usr/bin/foo2 { audit deny change_profile @{var} -> "/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_bad_2.sd0000644000175000017500000000022313502024172023635 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { deny owner change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_allow_re_ok_4.sd0000644000175000017500000000166113502024172024733 0ustar jjjj# #=DESCRIPTION allow change_profile /onexec with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{LIBVIRT_RE}="libvirt*" /usr/bin/foo { allow change_profile /onexec -> @{LIBVIRT}-fo*, } /usr/bin/foo2 { allow change_profile /onexec -> @{LIBVIRT}-fo**, } /usr/bin/foo3 { allow change_profile /onexec -> @{LIBVIRT}-fo[ab], } /usr/bin/foo4 { allow change_profile /onexec -> @{LIBVIRT}-fo[^ab], } /usr/bin/foo5 { allow change_profile /onexec -> @{LIBVIRT}-fo?, } /usr/bin/foo6 { allow change_profile /onexec -> @{LIBVIRT_RE}-foo, } /usr/bin/foo7 { allow change_profile /onexec -> @{LIBVIRT_RE}-fo*, } /usr/bin/foo8 { allow change_profile /onexec -> @{LIBVIRT_RE}-fo**, } /usr/bin/foo9 { allow change_profile /onexec -> @{LIBVIRT_RE}-fo?, } /usr/bin/foo10 { allow change_profile /onexec -> @{LIBVIRT_RE}-fo[ab], } /usr/bin/foo11 { allow change_profile /onexec -> @{LIBVIRT_RE}-fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_ok_5.sd0000644000175000017500000000036513502024172024061 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { audit change_profile @{var} -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_re_bad_2.sd0000644000175000017500000000023113502024172024463 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit deny owner change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ad_re_ok_5.sd0000644000175000017500000000062713502024172024714 0ustar jjjj# #=DESCRIPTION audit deny change_profile @{var} with just res #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit deny change_profile @{var} -> *, } /usr/bin/foo2 { audit deny change_profile @{var} -> **, } /usr/bin/foo3 { audit deny change_profile @{var} -> ?, } /usr/bin/foo4 { audit deny change_profile @{var} -> [ab], } /usr/bin/foo5 { audit deny change_profile @{var} -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aao_bad_7.sd0000644000175000017500000000023513502024172024003 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit allow owner change_profile /onexec -> "/bin/foo//bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_re_bad_6.sd0000644000175000017500000000020713502024172024165 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { owner change_profile /onexec -> *//ab, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_ok_5.sd0000644000175000017500000000033013502024172022457 0ustar jjjj# #=DESCRIPTION deny change_profile with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { deny change_profile -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aa_re_ok_3.sd0000644000175000017500000000224213502024172023305 0ustar jjjj# #=DESCRIPTION audit allow change_profile with name space #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile -> :foo:/bin/foo, } /usr/bin/foo2 { audit allow change_profile -> :foo:/bin/fo*, } /usr/bin/foo3 { audit allow change_profile -> :foo:/bin/fo**, } /usr/bin/foo4 { audit allow change_profile -> :foo:/bin/fo?, } /usr/bin/foo5 { audit allow change_profile -> :foo:/bin/fo[ab], } /usr/bin/foo6 { audit allow change_profile -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { audit allow change_profile -> :fo*:/bin/foo, } /usr/bin/foo8 { audit allow change_profile -> :fo**:/bin/foo, } /usr/bin/foo9 { audit allow change_profile -> :fo?:/bin/foo, } /usr/bin/foo10 { audit allow change_profile -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { audit allow change_profile -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { audit allow change_profile -> :fo*:/bin/fo*, } /usr/bin/foo13 { audit allow change_profile -> :fo**:/bin/fo**, } /usr/bin/foo14 { audit allow change_profile -> :fo?:/bin/fo?, } /usr/bin/foo15 { audit allow change_profile -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { audit allow change_profile -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_d_ok_2.sd0000644000175000017500000000022413502024172024053 0ustar jjjj# #=DESCRIPTION deny change_profile @{var} to a hat #=EXRESULT PASS # @{var}=/test /usr/bin/foo { deny change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_re_bad_5.sd0000644000175000017500000000022413502024172025040 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny owner change_profile @{var} -> *, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_o_bad_4.sd0000644000175000017500000000024613502024172023500 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" /usr/bin/foo { owner change_profile /onexec -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_bad_7.sd0000644000175000017500000000024213502024172024351 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit owner change_profile @{var} -> "/bin/foo//bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aa_re_ok_8.sd0000644000175000017500000000133013502024172023307 0ustar jjjj# #=DESCRIPTION audit allow change_profile re with quotes #=EXRESULT PASS # /usr/bin/foo5 { audit allow change_profile -> "/bin/*", } /usr/bin/foo6 { audit allow change_profile -> "/bin/**", } /usr/bin/foo7 { audit allow change_profile -> "/bin/[ab]", } /usr/bin/foo8 { audit allow change_profile -> "/bin/[^ab]", } /usr/bin/foo10 { audit allow change_profile -> "/bin/?ab", } /usr/bin/foo11 { audit allow change_profile -> "/bin/ *", } /usr/bin/foo12 { audit allow change_profile -> "/bin/ **", } /usr/bin/foo13 { audit allow change_profile -> "/bin/ [ab]", } /usr/bin/foo14 { audit allow change_profile -> "/bin/ [^ab]", } /usr/bin/foo15 { audit allow change_profile -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_do_bad_7.sd0000644000175000017500000000022513502024172023644 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { deny owner change_profile /onexec -> "/bin/foo//bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_a_ok_2.sd0000644000175000017500000000021313502024172023335 0ustar jjjj# #=DESCRIPTION audit change_profile /onexec to a hat #=EXRESULT PASS # /usr/bin/foo { audit change_profile /onexec -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_ok_5.sd0000644000175000017500000000035013502024172023345 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { deny change_profile /onexec -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_re_ok_5.sd0000644000175000017500000000052513502024172024245 0ustar jjjj# #=DESCRIPTION change_profile @{var} with just res #=EXRESULT PASS # @{var}=/test /usr/bin/foo { change_profile @{var} -> *, } /usr/bin/foo2 { change_profile @{var} -> **, } /usr/bin/foo3 { change_profile @{var} -> ?, } /usr/bin/foo4 { change_profile @{var} -> [ab], } /usr/bin/foo5 { change_profile @{var} -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/allow_re_ok_1.sd0000644000175000017500000000051413502024172024040 0ustar jjjj# #=DESCRIPTION allow change_profile #=EXRESULT PASS # /usr/bin/foo { allow change_profile -> /bin/*, } /usr/bin/foo2 { allow change_profile -> /bin/**, } /usr/bin/foo3 { allow change_profile -> /bin/?, } /usr/bin/foo4 { allow change_profile -> /bin/[ab], } /usr/bin/foo5 { allow change_profile -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_ok_8.sd0000644000175000017500000000036713502024172023521 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec with name space with quotes #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile /onexec -> ":foo:/bin/foo", } /usr/bin/foo2 { audit deny change_profile /onexec -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_re_ok_5.sd0000644000175000017500000000062013502024172024174 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec with just res #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile /onexec -> *, } /usr/bin/foo2 { audit deny change_profile /onexec -> **, } /usr/bin/foo3 { audit deny change_profile /onexec -> ?, } /usr/bin/foo4 { audit deny change_profile /onexec -> [ab], } /usr/bin/foo5 { audit deny change_profile /onexec -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/d_re_ok_5.sd0000644000175000017500000000047413502024172023156 0ustar jjjj# #=DESCRIPTION deny change_profile with just res #=EXRESULT PASS # /usr/bin/foo { deny change_profile -> *, } /usr/bin/foo2 { deny change_profile -> **, } /usr/bin/foo3 { deny change_profile -> ?, } /usr/bin/foo4 { deny change_profile -> [ab], } /usr/bin/foo5 { deny change_profile -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_ok_1.sd0000644000175000017500000000021013502024172024042 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} #=EXRESULT PASS # @{var}=/test /usr/bin/foo { audit change_profile @{var} -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_bare_bad_1.sd0000644000175000017500000000021613502024172025340 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny owner change_profile @{var}, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aao_re_bad_7.sd0000644000175000017500000000022413502024172024467 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit allow owner change_profile /onexec -> :ab:*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_ok_7.sd0000644000175000017500000000033013502024172022622 0ustar jjjj# #=DESCRIPTION audit deny change_profile to a hat with quotes #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile -> "/bin/foo//bar", } /usr/bin/foo2 { audit deny change_profile -> "/bin/foo// bar", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ok_1.sd0000644000175000017500000000016113502024172023036 0ustar jjjj# #=DESCRIPTION change_profile /onexec #=EXRESULT PASS # /usr/bin/foo { change_profile /onexec -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_bare_bad_1.sd0000644000175000017500000000016313502024172024612 0ustar jjjj# #=DESCRIPTION deny audit in wrong order #=EXRESULT FAIL # /usr/bin/foo { deny audit change_profile /onexec, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ad_re_ok_3.sd0000644000175000017500000000222113502024172023305 0ustar jjjj# #=DESCRIPTION audit deny change_profile with name space #=EXRESULT PASS # /usr/bin/foo { audit deny change_profile -> :foo:/bin/foo, } /usr/bin/foo2 { audit deny change_profile -> :foo:/bin/fo*, } /usr/bin/foo3 { audit deny change_profile -> :foo:/bin/fo**, } /usr/bin/foo4 { audit deny change_profile -> :foo:/bin/fo?, } /usr/bin/foo5 { audit deny change_profile -> :foo:/bin/fo[ab], } /usr/bin/foo6 { audit deny change_profile -> :foo:/bin/fo[^ab], } /usr/bin/foo7 { audit deny change_profile -> :fo*:/bin/foo, } /usr/bin/foo8 { audit deny change_profile -> :fo**:/bin/foo, } /usr/bin/foo9 { audit deny change_profile -> :fo?:/bin/foo, } /usr/bin/foo10 { audit deny change_profile -> :fo[ab]:/bin/foo, } /usr/bin/foo11 { audit deny change_profile -> :fo[^ab]:/bin/foo, } /usr/bin/foo12 { audit deny change_profile -> :fo*:/bin/fo*, } /usr/bin/foo13 { audit deny change_profile -> :fo**:/bin/fo**, } /usr/bin/foo14 { audit deny change_profile -> :fo?:/bin/fo?, } /usr/bin/foo15 { audit deny change_profile -> :fo[ab]:/bin/fo[ab], } /usr/bin/foo16 { audit deny change_profile -> :fo[^ab]:/bin/fo[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ok_8.sd0000644000175000017500000000032613502024172023050 0ustar jjjj# #=DESCRIPTION change_profile /onexec with name space with quotes #=EXRESULT PASS # /usr/bin/foo { change_profile /onexec -> ":foo:/bin/foo", } /usr/bin/foo2 { change_profile /onexec -> ":foo:/bin/ foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_allow_re_ok_5.sd0000644000175000017500000000057113502024172025444 0ustar jjjj# #=DESCRIPTION allow change_profile @{var} with just res #=EXRESULT PASS # @{var}=/test /usr/bin/foo { allow change_profile @{var} -> *, } /usr/bin/foo2 { allow change_profile @{var} -> **, } /usr/bin/foo3 { allow change_profile @{var} -> ?, } /usr/bin/foo4 { allow change_profile @{var} -> [ab], } /usr/bin/foo5 { allow change_profile @{var} -> [^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_d_re_ok_2.sd0000644000175000017500000000225613502024172024037 0ustar jjjj# #=DESCRIPTION deny change_profile /onexec to a hat #=EXRESULT PASS # /usr/bin/foo { deny change_profile /onexec -> /bin/foo//bar, } /usr/bin/foo2 { deny change_profile /onexec -> /bin/foo//ba*, } /usr/bin/foo3 { deny change_profile /onexec -> /bin/foo//ba**, } /usr/bin/foo4 { deny change_profile /onexec -> /bin/foo//ba?, } /usr/bin/foo5 { deny change_profile /onexec -> /bin/foo//ba[ab], } /usr/bin/foo6 { deny change_profile /onexec -> /bin/foo//ba[^ab], } /usr/bin/foo7 { deny change_profile /onexec -> /bin/fo*//bar, } /usr/bin/foo8 { deny change_profile /onexec -> /bin/fo**//bar, } /usr/bin/foo9 { deny change_profile /onexec -> /bin/fo?//bar, } /usr/bin/foo10 { deny change_profile /onexec -> /bin/fo[ab]//bar, } /usr/bin/foo11 { deny change_profile /onexec -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { deny change_profile /onexec -> /bin/fo*//ba*, } /usr/bin/foo13 { deny change_profile /onexec -> /bin/fo**//ba**, } /usr/bin/foo14 { deny change_profile /onexec -> /bin/fo?//ba?, } /usr/bin/foo15 { deny change_profile /onexec -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { deny change_profile /onexec -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ok_2.sd0000644000175000017500000000015713502024172022160 0ustar jjjj# #=DESCRIPTION change_profile to a hat #=EXRESULT PASS # /usr/bin/foo { change_profile -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ado_re_bad_5.sd0000644000175000017500000000021613502024172024471 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo { audit deny owner change_profile /onexec -> *, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_bad_6.sd0000644000175000017500000000023513502024172024352 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit owner change_profile @{var} -> "/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/stacking_ok_1.sd0000644000175000017500000000015613502024172024041 0ustar jjjj# #=DESCRIPTION change_profile w/ stacking #=EXRESULT PASS # /usr/bin/foo { change_profile -> &/bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ad_ok_4.sd0000644000175000017500000000030213502024172023502 0ustar jjjj# #=DESCRIPTION audit deny change_profile /onexec with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { audit deny change_profile /onexec -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_da_bad_6.sd0000644000175000017500000000021613502024172023625 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # /usr/bin/foo { deny audit change_profile /onexec -> "/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_allow_ok_4.sd0000644000175000017500000000030313502024172024746 0ustar jjjj# #=DESCRIPTION allow change_profile @{var} with a variable (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { allow change_profile @{var} -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_allow_re_ok_6.sd0000644000175000017500000000200513502024172025437 0ustar jjjj# #=DESCRIPTION allow change_profile @{var} with just res, child profile #=EXRESULT PASS # @{var}=/test /usr/bin/foo { allow change_profile @{var} -> *//ab, } /usr/bin/foo2 { allow change_profile @{var} -> **//ab, } /usr/bin/foo3 { allow change_profile @{var} -> ?//ab, } /usr/bin/foo4 { allow change_profile @{var} -> [ab]//ab, } /usr/bin/foo5 { allow change_profile @{var} -> [^ab]//ab, } /usr/bin/foo6 { allow change_profile @{var} -> ab//*, } /usr/bin/foo7 { allow change_profile @{var} -> ab//**, } /usr/bin/foo8 { allow change_profile @{var} -> ab//?, } /usr/bin/foo9 { allow change_profile @{var} -> ab//[ab], } /usr/bin/foo10 { allow change_profile @{var} -> ab//[^ab], } /usr/bin/foo11 { allow change_profile @{var} -> *//*, } /usr/bin/foo12 { allow change_profile @{var} -> **//*, } /usr/bin/foo13 { allow change_profile @{var} -> ?//*, } /usr/bin/foo14 { allow change_profile @{var} -> [ab]//*, } /usr/bin/foo15 { allow change_profile @{var} -> [^ab]//*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_aao_bad_5.sd0000644000175000017500000000035413502024172024514 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { audit allow owner change_profile @{var} -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aa_re_ok_2.sd0000644000175000017500000000223513502024172023306 0ustar jjjj# #=DESCRIPTION audit allow change_profile to a hat #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile -> /bin/foo//bar, } /usr/bin/foo2 { audit allow change_profile -> /bin/foo//ba*, } /usr/bin/foo3 { audit allow change_profile -> /bin/foo//ba**, } /usr/bin/foo4 { audit allow change_profile -> /bin/foo//ba?, } /usr/bin/foo5 { audit allow change_profile -> /bin/foo//ba[ab], } /usr/bin/foo6 { audit allow change_profile -> /bin/foo//ba[^ab], } /usr/bin/foo7 { audit allow change_profile -> /bin/fo*//bar, } /usr/bin/foo8 { audit allow change_profile -> /bin/fo**//bar, } /usr/bin/foo9 { audit allow change_profile -> /bin/fo?//bar, } /usr/bin/foo10 { audit allow change_profile -> /bin/fo[ab]//bar, } /usr/bin/foo11 { audit allow change_profile -> /bin/fo[^ab]//bar, } /usr/bin/foo12 { audit allow change_profile -> /bin/fo*//ba*, } /usr/bin/foo13 { audit allow change_profile -> /bin/fo**//ba**, } /usr/bin/foo14 { audit allow change_profile -> /bin/fo?//ba?, } /usr/bin/foo15 { audit allow change_profile -> /bin/fo[ab]//ba[ab], } /usr/bin/foo16 { audit allow change_profile -> /bin/fo[^ab]//ba[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/aa_re_ok_1.sd0000644000175000017500000000056013502024172023304 0ustar jjjj# #=DESCRIPTION audit allow change_profile #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile -> /bin/*, } /usr/bin/foo2 { audit allow change_profile -> /bin/**, } /usr/bin/foo3 { audit allow change_profile -> /bin/?, } /usr/bin/foo4 { audit allow change_profile -> /bin/[ab], } /usr/bin/foo5 { audit allow change_profile -> /bin/[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_aa_re_ok_7.sd0000644000175000017500000000215313502024172024176 0ustar jjjj# #=DESCRIPTION audit allow change_profile /onexec with just re, namespace #=EXRESULT PASS # /usr/bin/foo { audit allow change_profile /onexec -> :ab:*, } /usr/bin/foo2 { audit allow change_profile /onexec -> :ab:**, } /usr/bin/foo3 { audit allow change_profile /onexec -> :ab:?, } /usr/bin/foo4 { audit allow change_profile /onexec -> :ab:[ab], } /usr/bin/foo5 { audit allow change_profile /onexec -> :ab:[^ab], } /usr/bin/foo6 { audit allow change_profile /onexec -> :*:ab, } /usr/bin/foo7 { audit allow change_profile /onexec -> :**:ab, } /usr/bin/foo8 { audit allow change_profile /onexec -> :?:ab, } /usr/bin/foo9 { audit allow change_profile /onexec -> :[ab]:ab, } /usr/bin/foo10 { audit allow change_profile /onexec -> :[^ab]:ab, } /usr/bin/foo11 { audit allow change_profile /onexec -> :*:*, } /usr/bin/foo12 { audit allow change_profile /onexec -> :**:**, } /usr/bin/foo13 { audit allow change_profile /onexec -> :?:?, } /usr/bin/foo14 { audit allow change_profile /onexec -> :[ab]:[ab], } /usr/bin/foo15 { audit allow change_profile /onexec -> :[^ab]:[^ab], } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_ok_5.sd0000644000175000017500000000033613502024172023046 0ustar jjjj# #=DESCRIPTION change_profile /onexec with variable+regex (LP: #390810) #=EXRESULT PASS # @{LIBVIRT}="libvirt" /usr/bin/foo { change_profile /onexec -> @{LIBVIRT}-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onx_no_conflict_safe2.sd0000644000175000017500000000033113502024172025561 0ustar jjjj# #=DESCRIPTION 'safe' and 'unsafe' for the same exec condition, but different exec targets #=EXRESULT PASS # /usr/bin/foo { change_profile safe /onexec -> /bin/foo, change_profile unsafe /onexec -> /bin/bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/a_ok_2.sd0000644000175000017500000000017313502024172022456 0ustar jjjj# #=DESCRIPTION audit change_profile to a hat #=EXRESULT PASS # /usr/bin/foo { audit change_profile -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_o_bad_8.sd0000644000175000017500000000023413502024172024212 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { owner change_profile @{var} -> ":foo:/bin/foo", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_da_re_bad_6.sd0000644000175000017500000000022613502024172025025 0ustar jjjj# #=DESCRIPTION deny audit is wrong order for prefixes #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { deny audit change_profile @{var} -> *//ab, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/ok_1.sd0000644000175000017500000000014113502024172022150 0ustar jjjj# #=DESCRIPTION change_profile #=EXRESULT PASS # /usr/bin/foo { change_profile -> /bin/foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_a_re_ok_8.sd0000644000175000017500000000136113502024172024547 0ustar jjjj# #=DESCRIPTION audit change_profile @{var} re with quotes #=EXRESULT PASS # @{var}=/test /usr/bin/foo5 { audit change_profile @{var} -> "/bin/*", } /usr/bin/foo6 { audit change_profile @{var} -> "/bin/**", } /usr/bin/foo7 { audit change_profile @{var} -> "/bin/[ab]", } /usr/bin/foo8 { audit change_profile @{var} -> "/bin/[^ab]", } /usr/bin/foo10 { audit change_profile @{var} -> "/bin/?ab", } /usr/bin/foo11 { audit change_profile @{var} -> "/bin/ *", } /usr/bin/foo12 { audit change_profile @{var} -> "/bin/ **", } /usr/bin/foo13 { audit change_profile @{var} -> "/bin/ [ab]", } /usr/bin/foo14 { audit change_profile @{var} -> "/bin/ [^ab]", } /usr/bin/foo15 { audit change_profile @{var} -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ao_re_bad_8.sd0000644000175000017500000000022013502024172025034 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # /usr/bin/foo5 { audit owner change_profile @{var} -> "/bin/*", } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_ado_re_bad_2.sd0000644000175000017500000000024513502024172025201 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{var}=/test /usr/bin/foo { audit deny owner change_profile @{var} -> /bin/foo//bar, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/onxvar_do_bad_4.sd0000644000175000017500000000026713502024172024360 0ustar jjjj# #=DESCRIPTION owner not allowed in change_profile rule #=EXRESULT FAIL # @{LIBVIRT}="libvirt" @{var}=/test /usr/bin/foo { deny owner change_profile @{var} -> @{LIBVIRT}-foo, } apparmor-2.13.3/parser/tst/simple_tests/change_profile/re_ok_8.sd0000644000175000017500000000112413502024172022647 0ustar jjjj# #=DESCRIPTION change_profile re with quotes #=EXRESULT PASS # /usr/bin/foo5 { change_profile -> "/bin/*", } /usr/bin/foo6 { change_profile -> "/bin/**", } /usr/bin/foo7 { change_profile -> "/bin/[ab]", } /usr/bin/foo8 { change_profile -> "/bin/[^ab]", } /usr/bin/foo10 { change_profile -> "/bin/?ab", } /usr/bin/foo11 { change_profile -> "/bin/ *", } /usr/bin/foo12 { change_profile -> "/bin/ **", } /usr/bin/foo13 { change_profile -> "/bin/ [ab]", } /usr/bin/foo14 { change_profile -> "/bin/ [^ab]", } /usr/bin/foo15 { change_profile -> "/bin/ ?ab", } apparmor-2.13.3/parser/tst/minimize.sh0000755000175000017500000001642613502024172015504 0ustar jjjj#!/bin/bash # APPARMOR_PARSER="${APPARMOR_PARSER:-../apparmor_parser}" # Format of -D dfa-states # dfa-states output is split into 2 parts: # the accept state infomation # {state} (allow deny audit XXX) ignore XXX for now # followed by the transition table information # {Y} -> {Z}: 0xXX Char #0xXX is the hex dump of Char # where the start state is always shown as # {1} <== # # Eg. echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, deny /** w, }" | ./apparmor_parser -QT -O minimize -D dfa-states --quiet # # {1} <== (allow/deny/audit/quiet) # {3} (0x 0/2800a/0/2800a) # {4} (0x 10004/2800a/0/2800a) # {7} (0x 40010/2800a/0/2800a) # {8} (0x 80020/2800a/0/2800a) # {9} (0x 100040/2800a/0/2800a) # {c} (0x 40030/0/0/0) # # {1} -> {2}: 0x2f / # {2} -> {4}: 0x61 a # {2} -> {3}: 0x62 b # {2} -> {3}: 0x63 c # {2} -> {7}: 0x64 d # {2} -> {8}: 0x65 e # {2} -> {9}: 0x66 f # {2} -> {3}: [^\0x0/] # {3} -> {3}: [^\0x0] # {4} -> {3}: [^\0x0] # {7} -> {a}: 0x0 # {7} -> {3}: [] # {8} -> {3}: [^\0x0] # {9} -> {3}: [^\0x0] # {a} -> {b}: 0x2f / # {b} -> {c}: [^/] # {c} -> {c}: [] # # These tests currently only look at the accept state permissions # # To view any of these DFAs as graphs replace --D dfa-states with -D dfa-graph # strip of the test stuff around the parser command and use the the dot # command to convert # Eg. # echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, deny /** w, }" | ./apparmor_parser -QT -O minimize -D dfa-graph --quiet 2>min.graph # dot -T png -o min.png min.graph # and then view min.png in your favorite viewer # #------------------------------------------------------------------------ # test to see if minimization is eliminating non-redundant accept state # Test xtrans and regular perms separately. The are the same basic failure # but can xtrans has an extra code path. # # The permission test is setup to have all the none xtrans permissions show # up once on unique paths and have a global write permission that adds to # it. # This should result in a un-minimized dump looking like. Notice it has 6 # states with accept information, 1 for each rule except for the 'w' # permission which is combined into a single state for /b and /** # # {1} <== (allow/deny/audit/quiet) # {3} (0x 2800a/0/0/0) # {4} (0x 3800e/0/0/0) # {5} (0x 6801a/0/0/0) # {6} (0x a802a/0/0/0) # {7} (0x 12804a/0/0/0) # {a} (0x 40030/0/0/0) # A dump of minimization that is not respecting the uniqueness of the # permissions on the states looks like below. Notice it has only 3 states # with accept information # {1} <== (allow/deny/audit/quiet) # {3} (0x 1b806e/0/0/0) # {5} (0x 6801a/0/0/0) # {a} (0x 40030/0/0/0) echo -n "Minimize profiles basic perms " if [ `echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, /** w, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 6 ] ; then echo "failed" exit 1; fi echo "ok" # same test as above except with audit perms added # {1} <== (allow/deny/audit/quiet) # {3} (0x 2800a/0/2800a/0) # {4} (0x 3800e/0/2800a/0) # {7} (0x 6801a/0/2800a/0) # {8} (0x a802a/0/2800a/0) # {9} (0x 12804a/0/2800a/0) # {c} (0x 40030/0/0/0) echo -n "Minimize profiles audit perms " if [ `echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, audit /** w, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 6 ] ; then echo "failed" exit 1; fi echo "ok" # same test as above except with deny 'w' perm added to /**, this does not # elimnates the states with 'w' and 'a' because the quiet information is # being carried # # {1} <== (allow/deny/audit/quiet) # {3} (0x 0/2800a/0/2800a) # {4} (0x 10004/2800a/0/2800a) # {7} (0x 40010/2800a/0/2800a) # {8} (0x 80020/2800a/0/2800a) # {9} (0x 100040/2800a/0/2800a) # {c} (0x 40030/0/0/0) echo -n "Minimize profiles deny perms " if [ `echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, deny /** w, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 6 ] ; then echo "failed" exit 1; fi echo "ok" # same test as above except with audit deny 'w' perm added to /**, with the # parameter this elimnates the states with 'w' and 'a' because # the quiet information is NOT being carried # # {1} <== (allow/deny/audit/quiet) # {4} (0x 10004/0/0/0) # {7} (0x 40010/0/0/0) # {8} (0x 80020/0/0/0) # {9} (0x 100040/0/0/0) # {c} (0x 40030/0/0/0) echo -n "Minimize profiles audit deny perms " if [ `echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, audit deny /** w, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 5 ] ; then echo "failed" exit 1; fi echo "ok" # The x transition test profile is setup so that there are 3 conflicting x # permissions, two are on paths that won't collide during dfa creation. The # 3rd is a generic permission that should be overriden during dfa creation. # # This should result in a dfa that specifies transitions on 'a' and 'b' to # unique states that store the alternate accept information. However # minimization can remove the unique accept permission states if x permissions # are treated as a single accept state. # # The minimized dump should retain the 'a' and 'b' transitions accept states. # notice the below dump has 3 states with accept information {3}, {4}, {5} # # {1} <== (allow/deny/audit/quiet) # {3} (0x 2914a45/0/0/0) # {4} (0x 4115045/0/0/0) # {5} (0x 2514945/0/0/0) # # A dump of minimization that is not respecting the uniqueness of the # permissions on the states transitioned to by 'a' and 'b' looks like # below. Notice that only state {3} has accept information # {1} <== (allow/deny/audit/quiet) # {3} (0x 2514945/0/0/0) # echo -n "Minimize profiles xtrans " if [ `echo "/t { /b px, /* Pixr, /a Cx -> foo, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 3 ] ; then echo "failed" exit 1; fi echo "ok" # same test as above + audit echo -n "Minimize profiles audit xtrans " if [ `echo "/t { /b px, audit /* Pixr, /a Cx -> foo, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 3 ] ; then echo "failed" exit 1; fi echo "ok" # now try denying x and make sure perms are cleared # notice that only deny and quiet information is being carried # {1} <== (allow/deny/audit/quiet) # {3} (0x 0/fe17f85/0/14005) echo -n "Minimize profiles deny xtrans " if [ `echo "/t { /b px, deny /* xr, /a Cx -> foo, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 1 ] ; then echo "failed" exit 1; fi echo "ok" # now try audit + denying x and make sure perms are cleared # notice that the deny info is being carried, by an artifical trap state # {1} <== (allow/deny/audit/quiet) # {3} (0x 0/fe17f85/0/0) echo -n "Minimize profiles audit deny xtrans " if [ `echo "/t { /b px, audit deny /* xr, /a Cx -> foo, }" | ${APPARMOR_PARSER} -M features_files/features.nopolicydb -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 0 ] ; then echo "failed" exit 1; fi echo "ok" apparmor-2.13.3/parser/tst/testlib.py0000644000175000017500000001461113502024172015336 0ustar jjjj#!/usr/bin/env python3 # ------------------------------------------------------------------ # # Copyright (C) 2013 Canonical Ltd. # Author: Steve Beattie # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import os import shutil import signal import subprocess import tempfile import time import unittest TIMEOUT_ERROR_CODE = 152 DEFAULT_PARSER = '../apparmor_parser' # http://www.chiark.greenend.org.uk/ucgi/~cjwatson/blosxom/2009-07-02-python-sigpipe.html # This is needed so that the subprocesses that produce endless output # actually quit when the reader goes away. def subprocess_setup(): # Python installs a SIGPIPE handler by default. This is usually not # what non-Python subprocesses expect. signal.signal(signal.SIGPIPE, signal.SIG_DFL) class AANoCleanupMetaClass(type): def __new__(cls, name, bases, attrs): for attr_name, attr_value in attrs.items(): if attr_name.startswith("test_"): attrs[attr_name] = cls.keep_on_fail(attr_value) return super(AANoCleanupMetaClass, cls).__new__(cls, name, bases, attrs) @classmethod def keep_on_fail(cls, unittest_func): '''wrapping function for unittest testcases to detect failure and leave behind test files in tearDown(); to be used as a decorator''' def new_unittest_func(self): try: return unittest_func(self) except unittest.SkipTest: raise except Exception: self.do_cleanup = False raise return new_unittest_func class AATestTemplate(unittest.TestCase, metaclass=AANoCleanupMetaClass): '''Stub class for use by test scripts''' debug = False do_cleanup = True def run_cmd_check(self, command, input=None, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, stdin=None, timeout=120, expected_rc=0, expected_string=None): '''Wrapper around run_cmd that checks the rc code against expected_rc and for expected strings in the output if passed. The valgrind tests generally don't care what the rc is as long as it's not a specific set of return codes, so can't push the check directly into run_cmd().''' rc, report = self.run_cmd(command, input, stderr, stdout, stdin, timeout) self.assertEqual(rc, expected_rc, "Got return code %d, expected %d\nCommand run: %s\nOutput: %s" % (rc, expected_rc, (' '.join(command)), report)) if expected_string: self.assertIn(expected_string, report, 'Expected message "%s", got: \n%s' % (expected_string, report)) return report def run_cmd(self, command, input=None, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, stdin=None, timeout=120): '''Try to execute given command (array) and return its stdout, or return a textual error if it failed.''' if self.debug: print('\n===> Running command: \'%s\'' % (' '.join(command))) try: sp = subprocess.Popen(command, stdin=stdin, stdout=stdout, stderr=stderr, close_fds=True, preexec_fn=subprocess_setup) except OSError as e: return [127, str(e)] timeout_communicate = TimeoutFunction(sp.communicate, timeout) out, outerr = (None, None) try: out, outerr = timeout_communicate(input) rc = sp.returncode except TimeoutFunctionException as e: sp.terminate() outerr = b'test timed out, killed' rc = TIMEOUT_ERROR_CODE # Handle redirection of stdout if out is None: out = b'' # Handle redirection of stderr if outerr is None: outerr = b'' report = out.decode('utf-8') + outerr.decode('utf-8') return [rc, report] # Timeout handler using alarm() from John P. Speno's Pythonic Avocado class TimeoutFunctionException(Exception): """Exception to raise on a timeout""" pass class TimeoutFunction: def __init__(self, function, timeout): self.timeout = timeout self.function = function def handle_timeout(self, signum, frame): raise TimeoutFunctionException() def __call__(self, *args, **kwargs): old = signal.signal(signal.SIGALRM, self.handle_timeout) signal.alarm(self.timeout) try: result = self.function(*args, **kwargs) finally: signal.signal(signal.SIGALRM, old) signal.alarm(0) return result def filesystem_time_resolution(): '''detect whether the filesystem stores subsecond timestamps''' default_diff = 0.1 result = (True, default_diff) tmp_dir = tempfile.mkdtemp(prefix='aa-caching-nanostamp-') try: last_stamp = None for i in range(10): s = None with open(os.path.join(tmp_dir, 'test.%d' % i), 'w+') as f: s = os.fstat(f.fileno()) if (s.st_mtime == last_stamp): print('\n===> WARNING: TMPDIR lacks subsecond timestamp resolution, falling back to slower test') result = (False, 1.0) break last_stamp = s.st_mtime time.sleep(default_diff) except: pass finally: if os.path.exists(tmp_dir): shutil.rmtree(tmp_dir) return result def read_features_dir(path): result = '' if not os.path.exists(path) or not os.path.isdir(path): return result for name in os.listdir(path): entry = os.path.join(path, name) result += '%s {' % name if os.path.isfile(entry): with open(entry, 'r') as f: # don't need extra '\n' here as features file contains it result += '%s' % (f.read()) elif os.path.isdir(entry): result += '%s' % (read_features_dir(entry)) result += '}\n' return result def touch(path): return os.utime(path, None) def write_file(directory, file, contents): '''construct path, write contents to it, and return the constructed path''' path = os.path.join(directory, file) with open(path, 'w+') as f: f.write(contents) return path apparmor-2.13.3/parser/tst/README0000644000175000017500000000622213502024172014175 0ustar jjjjThis is the README for the AppArmor parser regression testsuite. Running the testsuite --------------------- Running the tests is pretty easy, a simple 'make tests' should make it go, assuming the subdomain parser and perl are installed. There is a user configuration file 'uservars.conf'. If you wish to test against a different parser, or use a different set of profiles for the simple.pl test, you can change those settings in 'uservars.conf'. You can also override which parser is used through make by specifying the PARSER veriable. For example, to run the tests on the system parser, run 'make PARSER=/sbin/apparmor_parser'. Adding to the testsuite ----------------------- The testsuite currently contains one testscript (simple.pl) and makes use of perl's Test::Simple, Test::Harness, and prove utilities (see 'perldoc Test::Tutorial', 'perldoc Test::Simple', 'perldoc Test::Harness', and 'man 1 prove' for more information on these). It should be relatively easy to extend the suite with other testscripts, as long as they're written using Test::Simple or can emulate the Test::Harness protocol. To add a script, add it to the TESTS variable in the Makefile, and it will included in the tests to be run. However, in many cases, it is not necessary to add an entire new testscript for a testcase. Instead, the simple testcase (see below) will run all the profiles it finds on the parser, thus adding testcases is usually as simple as writing a new profile with a couple of extra comments. Simple parsing tests (simple.pl) -------------------------------- This test script tests the parser front end's ability to identify legal profiles. It does this by running the parser against several legal and illegal profiles (in debug mode, so as not to load them into the module proper) The simple script has the parser attempt to parse all of the profiles named *.sd in the simple_tests/ subdirectory; thus, to add a new profile to test, simply add it to the simple_tests/ directory. The simple script also adds the testdir (simple_tests/ by default) to the parsers include path (assuming that particular bug has been fixed :-)). There is an includes/ subdir to place additional includes if necessary (we purposefully choose to use different directory names versus the shipped profiles to minimize testsuite breakage with changes in the external policy). The simple script looks for a few special comments in the profile, #=DESCRIPTION, #=EXRESULT, and #=TODO: - #=DESCRIPTION -- all text following the keyword is considered a description for the test. Please try to make these meaningful. - #=EXRESULT -- This records the expected result of parsing this profile. Values can either be PASS or FAIL; if no comment is found that matches this pattern, then the profile is assumed to have an expected parse result of PASS. - #=TODO -- marks the test as being for a future item to implement and thus are expected testsuite failures and hsould be ignored. - #=DISABLED -- skips the test, and marks it as a failed TODO task. Useful if the particular testcase causes the parser to infinite loop or dump core. Otherwise, the profile is passed on as-is to the subdomain parser. apparmor-2.13.3/parser/tst/Makefile0000644000175000017500000000446613502024172014765 0ustar jjjj# PROVE=/usr/bin/prove TESTS=simple.pl PARSER_DIR=.. PARSER_BIN=apparmor_parser PARSER=$(PARSER_DIR)/$(PARSER_BIN) # parser.conf to use in tests. Note that some test scripts have the parser options hardcoded, so passing PARSER_ARGS=... is not enough to override it. PARSER_ARGS=--config-file=./parser.conf PROVE_ARG=-f ifeq ($(VERBOSE),1) PROVE_ARG+=-v PYTEST_ARG = -v else VERBOSE= endif all: tests .PHONY: tests error_output gen_dbus gen_xtrans parser_sanity caching minimize equality valgrind tests: error_output caching minimize equality parser_sanity GEN_TRANS_DIRS=simple_tests/generated_x/ simple_tests/generated_perms_leading/ simple_tests/generated_perms_safe/ simple_tests/generated_dbus gen_xtrans: $(GEN_TRANS_DIRS) ./gen-xtrans.pl $(GEN_TRANS_DIRS): mkdir $@ gen_dbus: $(GEN_TRANS_DIRS) ./gen-dbus.pl error_output: $(PARSER) LANG=C $(PARSER) $(PARSER_ARGS) -S -I errors >/dev/null errors/okay.sd LANG=C $(PARSER) $(PARSER_ARGS) -S -I errors 2>&1 >/dev/null errors/single.sd | \ grep -q "AppArmor parser error for errors/single.sd in errors/single.sd at line 3: Could not open 'failure'" LANG=C $(PARSER) $(PARSER_ARGS) -S -I errors 2>&1 >/dev/null errors/double.sd | \ grep -q "AppArmor parser error for errors/double.sd in errors/includes/busted at line 66: Could not open 'does-not-exist'" LANG=C $(PARSER) $(PARSER_ARGS) -S -I errors 2>&1 >/dev/null errors/modefail.sd | \ grep -q "AppArmor parser error for errors/modefail.sd in errors/modefail.sd at line 6: syntax error" LANG=C $(PARSER) $(PARSER_ARGS) -S -I errors 2>&1 >/dev/null errors/multi_include.sd | \ grep -q "AppArmor parser error for errors/multi_include.sd in errors/multi_include.sd at line 12: Could not open 'failure'" @echo "Error Output: PASS" parser_sanity: $(PARSER) gen_xtrans gen_dbus $(Q)LANG=C APPARMOR_PARSER="$(PARSER)" ${PROVE} ${PROVE_ARG} ${TESTS} caching: $(PARSER) LANG=C ./caching.py -p "$(PARSER)" $(PYTEST_ARG) minimize: $(PARSER) LANG=C APPARMOR_PARSER="$(PARSER) $(PARSER_ARGS)" ./minimize.sh equality: $(PARSER) LANG=C APPARMOR_PARSER="$(PARSER) $(PARSER_ARGS)" ./equality.sh valgrind: $(PARSER) gen_xtrans gen_dbus LANG=C ./valgrind_simple.py -p "$(PARSER) $(PARSER_ARGS)" -v simple_tests $(PARSER): $(MAKE) -C $(PARSER_DIR) $(PARSER_BIN) clean: find $(GEN_TRANS_DIRS) -type f | xargs rm -f rm -f gmon.out apparmor-2.13.3/parser/tst/gen-dbus.pl0000755000175000017500000001417113502024172015363 0ustar jjjj#!/usr/bin/perl # # Copyright (c) 2013 # Canonical, Ltd. (All rights reserved) # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Canonical Ltd. # use strict; use Locale::gettext; use POSIX; setlocale(LC_MESSAGES, ""); my $count=0; my $prefix="simple_tests/generated_dbus"; my @quantifier = ("", "deny", "audit"); my @session = ("", "bus=session", "bus=system", "bus=accessibility"); my @path = ("", "path=/foo/bar", "path=\"/foo/bar\""); my @interface = ("", "interface=com.baz", "interface=\"com.baz\""); my @member = ("", "member=bar", "member=\"bar\""); my @name = ("", "name=com.foo", "name=\"com.foo\""); my @peer = map { "peer=($_)" } (@name, "label=/usr/bin/app", "label=\"/usr/bin/app\"", "name=com.foo label=/usr/bin/app", "name=\"com.foo\" label=\"/usr/bin/app\""); # @msg_perms are the permissions that are related to sending and receiving # messages. @svc_perms are the permissions related to services. my @base_msg_perms = ("r", "w", "rw", "read", "receive", "write", "send"); my @msg_perms = ("", @base_msg_perms, (map { "($_)" } @base_msg_perms), "(write, read)", "(send receive)", "(send read)", "(receive write)"); gen_files("message-rules", "PASS", \@quantifier, \@msg_perms, \@session, [""], \@path, \@interface, \@member, \@peer); gen_files("service-rules", "PASS", \@quantifier, ["bind"], \@session, \@name, [""], [""], [""], [""]); gen_files("eavesdrop-rules", "PASS", \@quantifier, ["eavesdrop"], \@session, [""], [""], [""], [""], [""]); gen_file("sloppy-formatting", "PASS", "", "(send , receive )", "bus=session", "", "path =\"/foo/bar\"", "interface = com.foo", " member=bar", "peer =( label= /usr/bin/app name =\"com.foo\")"); gen_file("sloppy-formatting", "PASS", "", "bind", "bus =session", "name= com.foo", "", "", "", ""); gen_file("sloppy-formatting", "PASS", "", "eavesdrop", "bus = system", "", "", "", "", ""); # Don't use the first element, which is empty, from each array since all empty # conditionals would PASS but we want all FAILs shift @msg_perms; shift @name; shift @path; shift @interface; shift @member; shift @peer; gen_files("message-incompat", "FAIL", \@quantifier, \@msg_perms, \@session, \@name, [""], [""], [""], [""]); gen_files("service-incompat", "FAIL", \@quantifier, ["bind"], \@session, \@name, \@path, [""], [""], [""]); gen_files("service-incompat", "FAIL", \@quantifier, ["bind"], \@session, \@name, [""], \@interface, [""], [""]); gen_files("service-incompat", "FAIL", \@quantifier, ["bind"], \@session, \@name, [""], [""], \@member, [""]); gen_files("service-incompat", "FAIL", \@quantifier, ["bind"], \@session, \@name, [""], [""], [""], \@peer); gen_files("eavesdrop-incompat", "FAIL", \@quantifier, ["eavesdrop"], \@session, \@name, \@path, \@interface, \@member, \@peer); gen_files("pairing-unsupported", "FAIL", \@quantifier, ["send", "bind"], \@session, ["name=sn", "label=sl"], [""], [""], [""], ["peer=(name=pn)", "peer=(label=pl)"]); # missing bus= prefix gen_file("bad-formatting", "FAIL", "", "send", "session", "", "", "", "", ""); # incorrectly formatted permissions gen_files("bad-perms", "FAIL", [""], ["send receive", "(send", "send)"], ["bus=session"], [""], [""], [""], [""], [""]); # invalid permissions gen_files("bad-perms", "FAIL", [""], ["a", "x", "Ux", "ix", "m", "k", "l", "(a)", "(x)"], [""], [""], [""], [""], [""], [""]); gen_file("duplicated-conditionals", "FAIL", "", "bus=1 bus=2"); gen_file("duplicated-conditionals", "FAIL", "", "name=1 name=2"); gen_file("duplicated-conditionals", "FAIL", "", "path=1 path=2"); gen_file("duplicated-conditionals", "FAIL", "", "interface=1 interface=2"); gen_file("duplicated-conditionals", "FAIL", "", "member=1 member=2"); gen_file("duplicated-conditionals", "FAIL", "", "peer=(name=1) peer=(name=2)"); gen_file("duplicated-conditionals", "FAIL", "", "peer=(label=1) peer=(label=2)"); gen_file("duplicated-conditionals", "FAIL", "", "peer=(name=1) peer=(label=2)"); print "Generated $count dbus tests\n"; sub print_rule($$$$$$$$$) { my ($file, $quantifier, $perms, $session, $name, $path, $interface, $member, $peer) = @_; print $file " "; print $file " ${quantifier}" if ${quantifier}; print $file " dbus"; print $file " ${perms}" if ${perms}; print $file " ${session}" if ${session}; print $file " ${name}" if ${name}; print $file " ${path}" if ${path}; print $file " ${interface}" if ${interface}; print $file " ${member}" if ${member}; print $file " ${peer}" if ${peer}; print $file ",\n"; } sub gen_file($$$$$$$$$$) { my ($test, $xres, $quantifier, $perms, $session, $name, $path, $interface, $member, $peer) = @_; my $file; unless (open $file, ">${prefix}/$test-$count.sd") { print("couldn't open $test\n"); exit 1; } print $file "#\n"; print $file "#=DESCRIPTION ${test}\n"; print $file "#=EXRESULT ${xres}\n"; print $file "#\n"; print $file "/usr/bin/foo {\n"; print_rule($file, $quantifier, $perms, $session, $name, $path, $interface, $member, $peer); print $file "}\n"; close($file); $count++; } sub gen_files($$$$$$$$$$) { my ($test, $xres, $quantifiers, $perms, $sessions, $names, $paths, $interfaces, $members, $peers) = @_; foreach my $quantifier (@{$quantifiers}) { foreach my $perm (@{$perms}) { foreach my $session (@{$sessions}) { foreach my $name (@{$names}) { foreach my $path (@{$paths}) { foreach my $interface (@{$interfaces}) { foreach my $member (@{$members}) { foreach my $peer (@{$peers}) { gen_file($test, $xres, $quantifier, $perm, $session, $name, $path, $interface, $member, $peer); } } } } } } } } } apparmor-2.13.3/parser/tst/errors/0000755000175000017500000000000013502024172014627 5ustar jjjjapparmor-2.13.3/parser/tst/errors/modefail.sd0000644000175000017500000000012713502024172016737 0ustar jjjj# 1 # 2 # 3 /does/not/exist { # 4 /lib/lib*.so rm, # 5 /fail abcdefgh, # 6 } # 7 apparmor-2.13.3/parser/tst/errors/okay.sd0000644000175000017500000000006113502024172016117 0ustar jjjj# /does/not/exist { #include } apparmor-2.13.3/parser/tst/errors/multi_include.sd0000644000175000017500000000025613502024172020017 0ustar jjjj# # # /does/not/exist { #include #include #include #include /bin/true rix, #include } apparmor-2.13.3/parser/tst/errors/double.sd0000644000175000017500000000011613502024172016427 0ustar jjjj# /does/not/exist { #include #include } apparmor-2.13.3/parser/tst/errors/single.sd0000644000175000017500000000011013502024172016430 0ustar jjjj# # #include # /does/not/exist { #include } apparmor-2.13.3/parser/tst/errors/includes/0000755000175000017500000000000013502024172016435 5ustar jjjjapparmor-2.13.3/parser/tst/errors/includes/busted0000644000175000017500000000571513502024172017656 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2002-2005 Novell/SUSE # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ # (Note that the ldd profile has inlined this file; if you make # modifications here, please consider including them in the ldd # profile as well.) # The __canary_death_handler function writes a time-stamped log # message to /dev/log for logging by syslogd. So, /dev/log, timezones, # and localisations of date should be available EVERYWHERE, so # StackGuard, FormatGuard, etc., alerts can be properly logged. /dev/log w, /dev/urandom r, /etc/locale/** r, /etc/localtime r, /usr/share/locale/** r, /usr/share/zoneinfo/** r, /usr/lib64/locale/** r, /usr/lib64/gconv/*.so r, /usr/lib64/gconv/gconv-modules* r, /usr/lib/locale/** r, /usr/lib/gconv/*.so r, /usr/lib/gconv/gconv-modules* r, # used by glibc when binding to ephemeral ports /etc/bindresvport.blacklist r, # ld.so.cache and ld are used to load shared libraries; they are best # available everywhere /etc/ld.so.cache r, # 'px' requires a profile to be available for the transition to # function; without a loaded profile, the kernel will fail the exec. /lib/ld-*.so px, /lib64/ld-*.so px, /opt/*-linux-uclibc/lib/ld-uClibc*so* px, # we might as well allow everything to use common libraries /lib/lib*.so* r, /lib/tls/lib*.so* r, /lib/power4/lib*.so* r, /lib/power5/lib*.so* r, /lib/power5+/lib*.so* r, /lib64/power4/lib*.so* r, /lib64/power5/lib*.so* r, /lib64/power5+/lib*.so* r, /usr/lib/*.so* r, /usr/lib/tls/lib*.so* r, /usr/lib/power4/lib*.so* r, /usr/lib/power5/lib*.so* r, /usr/lib/power5+/lib*.so* r, /lib64/lib*.so* r, /lib64/tls/lib*.so* r, /usr/lib64/*.so* r, /usr/lib64/tls/lib*.so* r, #include # /dev/null is pretty harmless and frequently used /dev/null rw, # as is /dev/zero /dev/zero rw, # Sometimes used to determine kernel/user interfaces to use /proc/sys/kernel/version r, # Depending on which glibc routine uses this file, base may not be the # best place -- but many profiles require it, and it is quite harmless. /proc/sys/kernel/ngroups_max r, # glibc's sysconf(3) routine to determine free memory, etc /proc/meminfo r, /proc/stat r, /proc/cpuinfo r, apparmor-2.13.3/parser/tst/errors/includes/base0000644000175000017500000000566013502024172017301 0ustar jjjj# ------------------------------------------------------------------ # # Copyright (C) 2002-2005 Novell/SUSE # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ # (Note that the ldd profile has inlined this file; if you make # modifications here, please consider including them in the ldd # profile as well.) # The __canary_death_handler function writes a time-stamped log # message to /dev/log for logging by syslogd. So, /dev/log, timezones, # and localisations of date should be available EVERYWHERE, so # StackGuard, FormatGuard, etc., alerts can be properly logged. /dev/log w, /dev/urandom r, /etc/locale/** r, /etc/localtime r, /usr/share/locale/** r, /usr/share/zoneinfo/** r, /usr/lib64/locale/** r, /usr/lib64/gconv/*.so r, /usr/lib64/gconv/gconv-modules* r, /usr/lib/locale/** r, /usr/lib/gconv/*.so r, /usr/lib/gconv/gconv-modules* r, # used by glibc when binding to ephemeral ports /etc/bindresvport.blacklist r, # ld.so.cache and ld are used to load shared libraries; they are best # available everywhere /etc/ld.so.cache r, # 'px' requires a profile to be available for the transition to # function; without a loaded profile, the kernel will fail the exec. /lib/ld-*.so px, /lib64/ld-*.so px, /opt/*-linux-uclibc/lib/ld-uClibc*so* px, # we might as well allow everything to use common libraries /lib/lib*.so* r, /lib/tls/lib*.so* r, /lib/power4/lib*.so* r, /lib/power5/lib*.so* r, /lib/power5+/lib*.so* r, /lib64/power4/lib*.so* r, /lib64/power5/lib*.so* r, /lib64/power5+/lib*.so* r, /usr/lib/*.so* r, /usr/lib/tls/lib*.so* r, /usr/lib/power4/lib*.so* r, /usr/lib/power5/lib*.so* r, /usr/lib/power5+/lib*.so* r, /lib64/lib*.so* r, /lib64/tls/lib*.so* r, /usr/lib64/*.so* r, /usr/lib64/tls/lib*.so* r, # /dev/null is pretty harmless and frequently used /dev/null rw, # as is /dev/zero /dev/zero rw, # Sometimes used to determine kernel/user interfaces to use /proc/sys/kernel/version r, # Depending on which glibc routine uses this file, base may not be the # best place -- but many profiles require it, and it is quite harmless. /proc/sys/kernel/ngroups_max r, # glibc's sysconf(3) routine to determine free memory, etc /proc/meminfo r, /proc/stat r, /proc/cpuinfo r, apparmor-2.13.3/parser/tst/mk_features_file.py0000755000175000017500000000214013502024172017171 0ustar jjjj#!/usr/bin/env python3 # ------------------------------------------------------------------ # # Copyright (C) 2014 Canonical Ltd. # Author: Steve Beattie # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ from testlib import read_features_dir from argparse import ArgumentParser import os from sys import stderr, exit DEFAULT_FEATURES_DIR='/sys/kernel/security/apparmor/features' def main(): p = ArgumentParser() p.add_argument('fdir', action="store", nargs='?', metavar="features_dir", default=DEFAULT_FEATURES_DIR, help="path to features directory") config = p.parse_args() if not os.path.exists(config.fdir): print('Unable to find apparmor features directory "%s"' % config.fdir, file=stderr) return 1 features = read_features_dir(config.fdir) print(features) return 0 if __name__ == "__main__": exit(main()) apparmor-2.13.3/parser/apparmor.pod0000644000175000017500000001662313502024172015036 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, # 2008, 2009 # NOVELL (All rights reserved) # # Copyright (c) 2010 # Canonical Ltd. (All rights reserved) # # Copyright (c) 2013 # Christian Boltz (All rights reserved) # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Novell, Inc. # ---------------------------------------------------------------------- =pod =head1 NAME AppArmor - kernel enhancement to confine programs to a limited set of resources. =head1 DESCRIPTION AppArmor is a kernel enhancement to confine programs to a limited set of resources. AppArmor's unique security model is to bind access control attributes to programs rather than to users. AppArmor confinement is provided via I loaded into the kernel via apparmor_parser(8), typically through the F SysV initscript, which is used like this: # /etc/init.d/apparmor start # /etc/init.d/apparmor stop # /etc/init.d/apparmor restart AppArmor can operate in two modes: I, and I: =over 4 =item * I - Profiles loaded in enforcement mode will result in enforcement of the policy defined in the profile as well as reporting policy violation attempts to syslogd. =item * I - Profiles loaded in C mode will not enforce policy. Instead, it will report policy violation attempts. This mode is convenient for developing profiles. To manage complain mode for individual profiles the utilities aa-complain(8) and aa-enforce(8) can be used. These utilities take a program name as an argument. =back Profiles are traditionally stored in files in F under filenames with the convention of replacing the B in pathnames with B<.> (except for the root B) so profiles are easier to manage (e.g. the F profile would be named F). Profiles are applied to a process at exec(3) time (as seen through the execve(2) system call): once a profile is loaded for a program, that program will be confined on the next exec(3). If a process is already running under a profile, when one replaces that profile in the kernel, the updated profile is applied immediately to that process. On the other hand, a process that is already running unconfined cannot be confined. AppArmor supports the Linux kernel's securityfs filesystem, and makes available the list of the profiles currently loaded; to mount the filesystem: # mount -tsecurityfs securityfs /sys/kernel/security $ cat /sys/kernel/security/apparmor/profiles /usr/bin/mutt /usr/bin/gpg ... Normally, the initscript will mount securityfs if it has not already been done. AppArmor also restricts what privileged operations a confined process may execute, even if the process is running as root. A confined process cannot call the following system calls: create_module(2) delete_module(2) init_module(2) ioperm(2) iopl(2) ptrace(2) reboot(2) setdomainname(2) sethostname(2) swapoff(2) swapon(2) sysctl(2) =head1 ERRORS When a confined process tries to access a file it does not have permission to access, the kernel will report a message through audit, similar to: audit(1386511672.612:238): apparmor="DENIED" operation="exec" parent=7589 profile="/tmp/sh" name="/bin/uname" pid=7605 comm="sh" requested_mask="x" denied_mask="x" fsuid=0 ouid=0 audit(1386511672.613:239): apparmor="DENIED" operation="open" parent=7589 profile="/tmp/sh" name="/bin/uname" pid=7605 comm="sh" requested_mask="r" denied_mask="r" fsuid=0 ouid=0 audit(1386511772.804:246): apparmor="DENIED" operation="capable" parent=7246 profile="/tmp/sh" pid=7589 comm="sh" pid=7589 comm="sh" capability=2 capname="dac_override" The permissions requested by the process are described in the operation= and denied_mask= (for files - capabilities etc. use a slightly different log format). The "name" and process id of the running program are reported, as well as the profile name including any "hat" that may be active, separated by "//". ("Name" is in quotes, because the process name is limited to 15 bytes; it is the same as reported through the Berkeley process accounting.) For confined processes running under a profile that has been loaded in complain mode, enforcement will not take place and the log messages reported to audit will be of the form: audit(1386512577.017:275): apparmor="ALLOWED" operation="open" parent=8012 profile="/usr/bin/du" name="/etc/apparmor.d/tunables/" pid=8049 comm="du" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0 audit(1386512577.017:276): apparmor="ALLOWED" operation="open" parent=8012 profile="/usr/bin/du" name="/etc/apparmor.d/tunables/" pid=8049 comm="du" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0 If the userland auditd is not running, the kernel will send audit events to klogd; klogd will send the messages to syslog, which will log the messages with the KERN facility. Thus, REJECTING and PERMITTING messages may go to either F or F, depending upon local configuration. =head1 DEBUGGING AppArmor provides a few facilities to log more information, which can help debugging profiles. =head2 Enable debug mode When debug mode is enabled, AppArmor will log a few extra messages to dmesg (not via the audit subsystem). For example, the logs will tell whether environment scrubbing has been applied. To enable debug mode, run: echo 1 > /sys/module/apparmor/parameters/debug =head2 Turn off deny audit quieting By default, operations that trigger C rules are not logged. This is called I. To turn off deny audit quieting, run: echo -n noquiet >/sys/module/apparmor/parameters/audit =head2 Force audit mode AppArmor can log a message for every operation that triggers a rule configured in the policy. This is called I. B Force audit mode can be extremely noisy even for a single profile, let alone when enabled globally. To set a specific profile in force audit mode, add the C flag: profile foo flags=(audit) { ... } To enable force audit mode globally, run: echo -n all > /sys/module/apparmor/parameters/audit If auditd is not running, to avoid losing too many of the extra log messages, you will likely have to turn off rate limiting by doing: echo 0 > /proc/sys/kernel/printk_ratelimit But even then the kernel ring buffer may overflow and you might lose messages. Else, if auditd is running, see auditd(8) and auditd.conf(5). =head1 FILES =over 4 =item F =item F =item F =item F =item F =back =head1 SEE ALSO apparmor_parser(8), aa_change_hat(2), apparmor.d(5), subdomain.conf(5), aa-autodep(1), clean(1), auditd(8), aa-unconfined(8), aa-enforce(1), aa-complain(1), and L. =cut apparmor-2.13.3/parser/apparmor_parser.pod0000644000175000017500000003024313502024172016404 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, # 2008, 2009 # NOVELL (All rights reserved) # # Copyright (c) 2010 - 2012 # Canonical Ltd. (All rights reserved) # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Novell, Inc. # ---------------------------------------------------------------------- =pod =head1 NAME apparmor_parser - loads AppArmor profiles into the kernel =head1 SYNOPSIS BcommandE [profiles]...> BcommandE> B =head1 DESCRIPTION B is used as a general tool to compile, and manage AppArmor policy, including loading new apparmor.d(5) profiles into the Linux kernel. AppArmor profiles restrict the operations available to processes. The B are loaded into the Linux kernel by the B program. The B may be specified by file name or a directory name containing a set of profiles. If a directory is specified then the B will try to do a profile load for each file in the directory that is not a dot file, or explicitly black listed (*.dpkg-new, *.dpkg-old, *.dpkg-dist, *.dpkg-bak, *.dpkg-remove, *.pacsave, *.pacnew, *.rpmnew, *.rpmsave, *.orig, *.rej, *~). The B will fall back to taking input from standard input if a profile or directory is not supplied. The input supplied to B should be in the format described in apparmor.d(5). =head1 COMMANDS The command set is broken into four subcategories. =over 4 =item unprivileged commands Commands that don't require any privilege and don't operate on profiles. =item unprivileged profile commands Commands that operate on a profile either specified on the command line or read from stdin if no profile was specified. =item privileged commands Commands that require the MAC_ADMIN capability within the affected AppArmor namespace to load policy into the kernel or filesystem write permissions to update the affected privileged files (cache etc). =item privileged profile commands Commands that require privilege and operate on profiles. =back =head1 Unprivileged commands =over 4 =item -V, --version Print the version number and exit. =item -h, --help Give a quick reference guide. =back =head1 Unprivileged profile commands =over 4 =item -N, --names Produce a list of policies from a given set of profiles (implies -K). =item -p, --preprocess Apply preprocessing to the input profile(s) by flattening includes into the output profile and dump to stdout. =item -S, --stdout Writes a binary (cached) profile to stdout (implies -K and -T). =item -o file, --ofile file Writes a binary (cached) profile to the specified file (implies -K and -T) =back =head1 Privileged commands =over 4 =item --purge-cache Unconditionally clear out cached profiles. =back =head1 Privileged profile commands =over 4 =item -a, --add Insert the AppArmor definitions given into the kernel. This is the default action. This gives an error message if a AppArmor definition by the same name already exists in the kernel, or if the parser doesn't understand its input. It reports when an addition succeeded. =item -r, --replace This flag is required if an AppArmor definition by the same name already exists in the kernel; used to replace the definition already in the kernel with the definition given on standard input. =item -R, --remove This flag is used to remove an AppArmor definition already in the kernel. Note that it still requires a complete AppArmor definition as described in apparmor.d(5) even though the contents of the definition aren't used. =back =head1 OPTIONS =over 4 =item -B, --binary Treat the profile files specified on the command line (or stdin if none specified) as binary cache files, produced with the -S or -o options, and load to the kernel as specified by -a, -r, and -R (implies -K and -T). =item -C, --Complain Force the profile to load in complain mode. =item -b n, --base n Set the base directory for resolving #include directives defined as relative paths. =item -I n, --Include n Add element n to the search path when resolving #include directives defined as an absolute paths. =item -f n, --subdomainfs n Set the location of the apparmor security filesystem (default is "/sys/kernel/security/apparmor"). =item -M n, --features-file n Use the features file located at path "n" (default is /etc/apparmor.d/cache/.features). If the --cache-loc option is present, the ".features" file in the specified cache directory is used. =item -m n, --match-string n Only use match features "n". =item -n n, --namespace-string n Force a profile to load in the namespace "n". =item -X, --readimpliesX In the case of profiles that are loading on systems were READ_IMPLIES_EXEC is set in the kernel for a given process, load the profile so that any "r" flags are processed as "mr". =item -k, --show-cache Report the cache processing (hit/miss details) when loading or saving cached profiles. =item -K, --skip-cache Perform no caching at all: disables -W, implies -T. =item -T, --skip-read-cache By default, if a profile's cache is found in the location specified by --cache-loc and the timestamp is newer than the profile, it will be loaded from the cache. This option disables this cache loading behavior. =item -W, --write-cache Write out cached profiles to the location specified in --cache-loc. Off by default. In cases where abstractions have been changed, and the parser is running with "--replace", it may make sense to also use "--skip-read-cache" with the "--write-cache" option. =item --skip-bad-cache Skip updating the cache if it contains cached profiles in a bad or inconsistent state =item -L, --cache-loc Set the location(s) of the cache directory. This option can accept a comma separated list of directories, which will be searched in order to find a matching cache. The first matching cache file found is used even if a directory later in the search order may contain a newer cache file. If multiple directories are specified and --write-cache has been specified then cache writes will be made to the first directory in the list, all other directories will be treated as read only. If a cache directory name needs to have a comma as part of the name, it can be specified by using a backslash to escape the comma character in the directory name. If not specified the cache location defaults to /var/cache/apparmor =item --print-cache-dir Print the cache directory location. This path will be a subdirectory of the directory specified by --cache-loc. The subdirectory used will be influenced by the features available in the currently running kernel or by the features specified with the --match-string or --features-file options. =item -Q, --skip-kernel-load Perform all actions except the actual loading of a profile into the kernel. This is useful for testing profile generation, caching, etc, without making changes to the running kernel profiles. This also removes the need for privilege to execute the commands that manage policy in the kernel =item -q, --quiet Do not report on the profiles as they are loaded, and not show warnings. =item -v, --verbose Report on the profiles as they are loaded, and show warnings. =item --warn=n Enable various warnings during policy compilation. A single dump flag can be specified per --warn option, but the --warn flag can be passed multiple times. apparmor_parser --warn=rules-not-enforced ... Use --help=warn to see a full list of which warn flags are supported. =item -d, --debug Given once, only checks the profiles to ensure syntactic correctness. Given twice, dumps its interpretation of the profile for checking. =item -D n, --dump=n Debug flag for dumping various structures and passes of policy compilation. A single dump flag can be specified per --dump option, but the dump flag can be passed multiple times. Note progress flags tend to also imply the matching stats flag. apparmor_parser --dump=dfa-stats --dump=trans-stats Use --help=dump to see a full list of which dump flags are supported =item -j n, --jobs=n Set the number of jobs used to compile the specified policy. Where n can be # - a specific number of jobs auto - the # of cpus in the in the system x# - # * number of cpus Eg. -j8 OR --jobs=8 allows for 8 parallel jobs -jauto OR --jobs=auto sets the jobs to the # of cpus -jx4 OR --jobs=x4 sets the jobs to # of cpus * 4 -jx1 is equivalent to -jauto The default value is the number of cpus in the system. =item --max-jobs n Set a hard cap on the value that can be specified by the --jobs flag. It takes the same set of options available to the --jobs option, and defaults to 8*cpus =item -O n, --optimize=n Set the optimization flags used by policy compilation. A single optimization flag can be toggled per -O option, but the optimize flag can be passed multiple times. Turning off some phases of the optimization can make it so that policy can't complete compilation due to size constraints (it is entirely possible to create a dfa with millions of states that will take days or longer to compile). Note: The parser is set to use a balanced default set of flags, that will result in reasonable compression but not take excessive amounts of time to complete. Use --help=optimize to see a full list of which optimization flags are supported. =item --abort-on-error Abort processing of profiles on the first error encountered, otherwise the parser will continue to try to compile other profiles if specified. Note: If an error is encountered while processing profiles the last error encountered will be used to set the exit code. =item --skip-bad-cache-rebuild The default behavior of the parser is to check if a cached version of a profile exists and if it does it attempt to load it into the kernel. If that load is rejected, then the parser will attempt to rebuild the cache file, and load again. This option tells the parser to not attempt to rebuild the cache on failure, instead the parser continues on with processing the remaining profiles. =item --config-file Specify the config file to use instead of /etc/apparmor/parser.conf. This option will be processed early before regular options regardless of the order it is specified in. =item --print-config-file Print the config file location that will be used. =back =head1 CONFIG FILE An optional config file /etc/apparmor/parser.conf can be used to specify the default options for the parser, which then can be overridden using the command line options. The config file ignores leading whitespace and treats lines that begin with # as comments. Config options are specified one per line using the same format as the longform command line options (without the preceding --). Eg. #comment optimize=no-expr-tree optimize=compress-fast As with the command line some options accumulate and others override, ie. when there are conflicting versions of switch the last option is the one chosen. Eg. Optimize=no-minimize Optimize=minimize would result in Optimize=minimize being set. The Include, Dump, and Optimize options accululate except for the inversion option (no-X vs. X), and a couple options that work by setting/clearing multiple options (compress-small). In that case the option will override the flags it sets but will may accumulate with others. All other options override previously set values. =head1 BUGS If you find any bugs, please report them at L. =head1 SEE ALSO apparmor(7), apparmor.d(5), subdomain.conf(5), aa_change_hat(2), and L. =cut apparmor-2.13.3/parser/parser_variable.c0000644000175000017500000003756313502024172016024 0ustar jjjj/* * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 * NOVELL (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. */ #include #include #include #include #include #include #include #include /* #define DEBUG */ #include "parser.h" #include "profile.h" #include "mount.h" #include "dbus.h" static inline const char *get_var_end(const char *var) { const char *eptr = var; while (*eptr) { if (*eptr == '}') return eptr; /* first character must be alpha */ if (eptr == var) { if (!isalpha(*eptr)) return NULL; /* invalid char */ } else { if (!(*eptr == '_' || isalnum(*eptr))) return NULL; /* invalid char */ } eptr++; } return NULL; /* no terminating '}' */ } static struct var_string *split_string(const char *string, const char *var_begin, const char *var_end) { struct var_string *n = (struct var_string *) calloc(1, sizeof(struct var_string)); unsigned int offset = strlen("@{"); if (!n) { PERROR("Memory allocation error\n"); return NULL; } if (var_begin != string) { n->prefix = strndup(string, var_begin - string); } n->var = strndup(var_begin + offset, var_end - (var_begin + offset)); if (strlen(var_end + 1) != 0) { n->suffix = strdup(var_end + 1); } return n; } struct var_string *split_out_var(const char *string) { struct var_string *n = NULL; const char *sptr; BOOL bEscape = 0; /* flag to indicate escape */ if (!string) /* shouldn't happen */ return NULL; sptr = string; while (!n && *sptr) { switch (*sptr) { case '\\': if (bEscape) { bEscape = FALSE; } else { bEscape = TRUE; } break; case '@': if (bEscape) { bEscape = FALSE; } else if (*(sptr + 1) == '{') { const char *eptr = get_var_end(sptr + 2); if (!eptr) break; /* no variable end found */ if (eptr == sptr + 2) { /* XXX - better diagnostics here, please */ PERROR("Empty variable name found!\n"); exit(1); } n = split_string(string, sptr, eptr); } break; default: if (bEscape) bEscape = FALSE; } sptr++; } return n; } void free_var_string(struct var_string *var) { if (!var) return; if (var->prefix) free(var->prefix); if (var->var) free(var->var); if (var->suffix) free(var->suffix); free(var); } static void trim_trailing_slash(std::string& str) { std::size_t found = str.find_last_not_of('/'); if (found != std::string::npos) str.erase(found + 1); else str.clear(); // str is all '/' } static void write_replacement(const char separator, const char* value, std::string& replacement, bool filter_leading_slash, bool filter_trailing_slash) { const char *p = value; replacement.append(1, separator); if (filter_leading_slash) while (*p == '/') p++; replacement.append(p); if (filter_trailing_slash) trim_trailing_slash(replacement); } static int expand_by_alternations(struct set_value **valuelist, struct var_string *split_var, char **name) { char *value, *first_value; std::string replacement; bool filter_leading_slash = false; bool filter_trailing_slash = false; first_value = get_next_set_value(valuelist); if (!first_value) { PERROR("ASSERT: set variable (%s) should always have at least one value assigned to it\n", split_var->var); exit(1); } free(*name); value = get_next_set_value(valuelist); if (!value) { /* only one entry for the variable, so just sub it in */ if (asprintf(name, "%s%s%s", split_var->prefix ? split_var->prefix : "", first_value, split_var->suffix ? split_var->suffix : "") == -1) return -1; return 0; } if (split_var->prefix && split_var->prefix[strlen(split_var->prefix) - 1] == '/') filter_leading_slash = true; if (split_var->suffix && *split_var->suffix == '/') filter_trailing_slash = true; write_replacement('{', first_value, replacement, filter_leading_slash, filter_trailing_slash); write_replacement(',', value, replacement, filter_leading_slash, filter_trailing_slash); while ((value = get_next_set_value(valuelist))) { write_replacement(',', value, replacement, filter_leading_slash, filter_trailing_slash); } if (asprintf(name, "%s%s}%s", split_var->prefix ? split_var->prefix : "", replacement.c_str(), split_var->suffix ? split_var->suffix : "") == -1) { return -1; } return 0; } /* doesn't handle variables in options atm */ int expand_entry_variables(char **name) { struct set_value *valuelist; struct var_string *split_var; int ret; assert(name); if (!*name) /* can happen when entry is optional */ return 0; while ((split_var = split_out_var(*name))) { valuelist = get_set_var(split_var->var); if (!valuelist) { int boolean = get_boolean_var(split_var->var); if (boolean == -1) PERROR("Found reference to variable %s, but is never declared\n", split_var->var); else PERROR("Found reference to set variable %s, but declared boolean\n", split_var->var); exit(1); } ret = expand_by_alternations(&valuelist, split_var, name); free_var_string(split_var); if (ret != 0) return -1; } return 0; } static int process_variables_in_entries(struct cod_entry *entry_list) { int error = 0; struct cod_entry *entry; list_for_each(entry_list, entry) { error = expand_entry_variables(&entry->name); if (error) return error; if (entry->link_name) { error = expand_entry_variables(&entry->link_name); if (error) return error; } } return 0; } static int process_variables_in_rules(Profile &prof) { for (RuleList::iterator i = prof.rule_ents.begin(); i != prof.rule_ents.end(); i++) { int error = (*i)->expand_variables(); if (error) return error; } return 0; } static int process_variables_in_name(Profile &prof) { /* this needs to be done before alias expansion, ie. altnames are * setup */ int error = expand_entry_variables(&prof.name); if (!error && prof.attachment) error = expand_entry_variables(&prof.attachment); return error; } static std::string escape_re(std::string str) { for (size_t i = 0; i < str.length(); i++) { if (str[i] == '\\') { /* skip \ and follow char. Skipping \ and first * char is enough for multichar escape sequence */ i++; continue; } if (strchr("{}[]*?", str[i]) != NULL) { str.insert(i++, "\\"); } } return str; } int process_profile_variables(Profile *prof) { int error = 0, rc; /* needs to be before PROFILE_NAME_VARIABLE so that variable will * have the correct name */ error = process_variables_in_name(*prof); if (!error) { /* escape profile name elements that could be interpreted * as regular expressions. */ error = new_set_var(PROFILE_NAME_VARIABLE, escape_re(prof->get_name(false)).c_str()); } if (!error) error = process_variables_in_entries(prof->entries); if (!error) error = process_variables_in_rules(*prof); rc = delete_set_var(PROFILE_NAME_VARIABLE); if (!error) error = rc; return error; } #ifdef UNIT_TEST #include "unit_test.h" int test_get_var_end(void) { int rc = 0; const char *retchar; const char *testchar; testchar = "TRUE}"; retchar = get_var_end(testchar); MY_TEST(retchar - testchar == strlen("TRUE"), "get var end for TRUE}"); testchar = "some_var}some other text"; retchar = get_var_end(testchar); MY_TEST(retchar - testchar == strlen("some_var"), "get var end for some_var}"); testchar = "some_var}some other} text"; retchar = get_var_end(testchar); MY_TEST(retchar - testchar == strlen("some_var"), "get var end for some_var} 2"); testchar = "FALSE"; retchar = get_var_end(testchar); MY_TEST(retchar == NULL, "get var end for FALSE"); testchar = "pah,pah}pah "; retchar = get_var_end(testchar); MY_TEST(retchar == NULL, "get var end for pah,pah}"); return rc; } int test_split_string(void) { int rc = 0; char *tst_string, *var_start, *var_end; struct var_string *ret_struct; const char *prefix = "abcdefg"; const char *var = "boogie"; const char *suffix = "suffixication"; asprintf(&tst_string, "%s@{%s}%s", prefix, var, suffix); var_start = tst_string + strlen(prefix); var_end = var_start + strlen(var) + strlen("@\{"); ret_struct = split_string(tst_string, var_start, var_end); MY_TEST(strcmp(ret_struct->prefix, prefix) == 0, "split string 1 prefix"); MY_TEST(strcmp(ret_struct->var, var) == 0, "split string 1 var"); MY_TEST(strcmp(ret_struct->suffix, suffix) == 0, "split string 1 suffix"); free_var_string(ret_struct); free(tst_string); asprintf(&tst_string, "@{%s}%s", var, suffix); var_start = tst_string; var_end = var_start + strlen(var) + strlen("@\{"); ret_struct = split_string(tst_string, var_start, var_end); MY_TEST(ret_struct->prefix == NULL, "split string 2 prefix"); MY_TEST(strcmp(ret_struct->var, var) == 0, "split string 2 var"); MY_TEST(strcmp(ret_struct->suffix, suffix) == 0, "split string 2 suffix"); free_var_string(ret_struct); free(tst_string); asprintf(&tst_string, "%s@{%s}", prefix, var); var_start = tst_string + strlen(prefix); var_end = var_start + strlen(var) + strlen("@\{"); ret_struct = split_string(tst_string, var_start, var_end); MY_TEST(strcmp(ret_struct->prefix, prefix) == 0, "split string 3 prefix"); MY_TEST(strcmp(ret_struct->var, var) == 0, "split string 3 var"); MY_TEST(ret_struct->suffix == NULL, "split string 3 suffix"); free_var_string(ret_struct); free(tst_string); asprintf(&tst_string, "@{%s}", var); var_start = tst_string; var_end = var_start + strlen(var) + strlen("@\{"); ret_struct = split_string(tst_string, var_start, var_end); MY_TEST(ret_struct->prefix == NULL, "split string 4 prefix"); MY_TEST(strcmp(ret_struct->var, var) == 0, "split string 4 var"); MY_TEST(ret_struct->suffix == NULL, "split string 4 suffix"); free_var_string(ret_struct); free(tst_string); return rc; } int test_split_out_var(void) { int rc = 0; char *tst_string, *tmp; struct var_string *ret_struct; const char *prefix = "abcdefg"; const char *var = "boogie"; const char *var2 = "V4rW1thNum5"; const char *var3 = "boogie_board"; const char *suffix = "suffixication"; /* simple case */ asprintf(&tst_string, "%s@{%s}%s", prefix, var, suffix); ret_struct = split_out_var(tst_string); MY_TEST(strcmp(ret_struct->prefix, prefix) == 0, "split out var 1 prefix"); MY_TEST(strcmp(ret_struct->var, var) == 0, "split out var 1 var"); MY_TEST(strcmp(ret_struct->suffix, suffix) == 0, "split out var 1 suffix"); free_var_string(ret_struct); free(tst_string); /* no prefix */ asprintf(&tst_string, "@{%s}%s", var, suffix); ret_struct = split_out_var(tst_string); MY_TEST(ret_struct->prefix == NULL, "split out var 2 prefix"); MY_TEST(strcmp(ret_struct->var, var) == 0, "split out var 2 var"); MY_TEST(strcmp(ret_struct->suffix, suffix) == 0, "split out var 2 suffix"); free_var_string(ret_struct); free(tst_string); /* no suffix */ asprintf(&tst_string, "%s@{%s}", prefix, var); ret_struct = split_out_var(tst_string); MY_TEST(strcmp(ret_struct->prefix, prefix) == 0, "split out var 3 prefix"); MY_TEST(strcmp(ret_struct->var, var) == 0, "split out var 3 var"); MY_TEST(ret_struct->suffix == NULL, "split out var 3 suffix"); free_var_string(ret_struct); free(tst_string); /* var only */ asprintf(&tst_string, "@{%s}", var); ret_struct = split_out_var(tst_string); MY_TEST(ret_struct->prefix == NULL, "split out var 4 prefix"); MY_TEST(strcmp(ret_struct->var, var) == 0, "split out var 4 var"); MY_TEST(ret_struct->suffix == NULL, "split out var 4 suffix"); free_var_string(ret_struct); free(tst_string); /* quoted var, shouldn't split */ asprintf(&tst_string, "%s\\@{%s}%s", prefix, var, suffix); ret_struct = split_out_var(tst_string); MY_TEST(ret_struct == NULL, "split out var - quoted @"); free_var_string(ret_struct); free(tst_string); /* quoted \, split should succeed */ asprintf(&tst_string, "%s\\\\@{%s}%s", prefix, var, suffix); ret_struct = split_out_var(tst_string); tmp = strndup(tst_string, strlen(prefix) + 2); MY_TEST(strcmp(ret_struct->prefix, tmp) == 0, "split out var 5 prefix"); MY_TEST(strcmp(ret_struct->var, var) == 0, "split out var 5 var"); MY_TEST(strcmp(ret_struct->suffix, suffix) == 0, "split out var 5 suffix"); free_var_string(ret_struct); free(tst_string); free(tmp); /* un terminated var, should fail */ asprintf(&tst_string, "%s@{%s%s", prefix, var, suffix); ret_struct = split_out_var(tst_string); MY_TEST(ret_struct == NULL, "split out var - un-terminated var"); free_var_string(ret_struct); free(tst_string); /* invalid char in var, should fail */ asprintf(&tst_string, "%s@{%s^%s}%s", prefix, var, var, suffix); ret_struct = split_out_var(tst_string); MY_TEST(ret_struct == NULL, "split out var - invalid char in var"); free_var_string(ret_struct); free(tst_string); /* two vars, should only strip out first */ asprintf(&tmp, "@{%s}%s}", suffix, suffix); asprintf(&tst_string, "%s@{%s}%s", prefix, var, tmp); ret_struct = split_out_var(tst_string); MY_TEST(strcmp(ret_struct->prefix, prefix) == 0, "split out var 6 prefix"); MY_TEST(strcmp(ret_struct->var, var) == 0, "split out var 6 var"); MY_TEST(strcmp(ret_struct->suffix, tmp) == 0, "split out var 6 suffix"); free_var_string(ret_struct); free(tst_string); free(tmp); /* quoted @ followed by var, split should succeed */ asprintf(&tst_string, "%s\\@@{%s}%s", prefix, var, suffix); ret_struct = split_out_var(tst_string); tmp = strndup(tst_string, strlen(prefix) + 2); MY_TEST(strcmp(ret_struct->prefix, tmp) == 0, "split out var 7 prefix"); MY_TEST(strcmp(ret_struct->var, var) == 0, "split out var 7 var"); MY_TEST(strcmp(ret_struct->suffix, suffix) == 0, "split out var 7 suffix"); free_var_string(ret_struct); free(tst_string); free(tmp); /* numeric char in var, should succeed */ asprintf(&tst_string, "%s@{%s}%s", prefix, var2, suffix); ret_struct = split_out_var(tst_string); MY_TEST(ret_struct && strcmp(ret_struct->prefix, prefix) == 0, "split out numeric var prefix"); MY_TEST(ret_struct && strcmp(ret_struct->var, var2) == 0, "split numeric var var"); MY_TEST(ret_struct && strcmp(ret_struct->suffix, suffix) == 0, "split out numeric var suffix"); free_var_string(ret_struct); free(tst_string); /* numeric first char in var, should fail */ asprintf(&tst_string, "%s@{6%s}%s", prefix, var2, suffix); ret_struct = split_out_var(tst_string); MY_TEST(ret_struct == NULL, "split out var - numeric first char in var"); free_var_string(ret_struct); free(tst_string); /* underscore char in var, should succeed */ asprintf(&tst_string, "%s@{%s}%s", prefix, var3, suffix); ret_struct = split_out_var(tst_string); MY_TEST(ret_struct && strcmp(ret_struct->prefix, prefix) == 0, "split out underscore var prefix"); MY_TEST(ret_struct && strcmp(ret_struct->var, var3) == 0, "split out underscore var"); MY_TEST(ret_struct && strcmp(ret_struct->suffix, suffix) == 0, "split out underscore var suffix"); free_var_string(ret_struct); free(tst_string); /* underscore first char in var, should fail */ asprintf(&tst_string, "%s@{_%s%s}%s", prefix, var2, var3, suffix); ret_struct = split_out_var(tst_string); MY_TEST(ret_struct == NULL, "split out var - underscore first char in var"); free_var_string(ret_struct); free(tst_string); return rc; } int main(void) { int rc = 0; int retval; retval = test_get_var_end(); if (retval != 0) rc = retval; retval = test_split_string(); if (retval != 0) rc = retval; retval = test_split_out_var(); if (retval != 0) rc = retval; return rc; } #endif /* UNIT_TEST */ apparmor-2.13.3/parser/rc.apparmor.debian0000644000175000017500000000502513502024172016073 0ustar jjjj#!/bin/sh # ---------------------------------------------------------------------- # Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 # NOVELL (All rights reserved) # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, contact Novell, Inc. # ---------------------------------------------------------------------- # rc.apparmor by Steve Beattie # # /etc/init.d/apparmor # # chkconfig: 2345 01 99 # description: AppArmor rc file. This rc script inserts the apparmor \ # module and runs the parser on the /etc/apparmor.d/ \ # directory. # ### BEGIN INIT INFO # Provides: apparmor # Required-Start: # Required-Stop: # Default-Start: 3 4 5 # Default-Stop: 0 1 2 6 # Short-Description: AppArmor initialization # Description: AppArmor rc file. This rc script inserts the apparmor # module and runs the parser on the /etc/apparmor.d/ # directory. ### END INIT INFO APPARMOR_FUNCTIONS=/lib/apparmor/rc.apparmor.functions aa_action() { STRING=$1 shift $* rc=$? if [ $rc -eq 0 ] ; then aa_log_success_msg $"$STRING " else aa_log_failure_msg $"$STRING " fi return $rc } aa_log_success_msg() { [ -n "$1" ] && echo -n $1 echo ": done." } aa_log_warning_msg() { [ -n "$1" ] && echo -n $1 echo ": Warning." } aa_log_failure_msg() { [ -n "$1" ] && echo -n $1 echo ": Failed." } aa_log_skipped_msg() { [ -n "$1" ] && echo -n $1 echo ": Skipped." } usage() { echo "Usage: $0 {start|stop|restart|try-restart|reload|force-reload|status|kill}" } # source apparmor function library if [ -f "${APPARMOR_FUNCTIONS}" ]; then . ${APPARMOR_FUNCTIONS} else aa_log_failure_msg "Unable to find AppArmor initscript functions" exit 1 fi test -x ${PARSER} || exit 0 # by debian policy case "$1" in start) apparmor_start rc=$? ;; stop) apparmor_stop rc=$? ;; restart|reload|force-reload) apparmor_restart rc=$? ;; try-restart) apparmor_try_restart rc=$? ;; kill) apparmor_kill rc=$? ;; status) apparmor_status rc=$? ;; *) usage exit 1 ;; esac exit $rc apparmor-2.13.3/parser/policy_cache.c0000644000175000017500000001176613502024172015302 0ustar jjjj/* * Copyright (c) 2014 * Canonical, Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical * Ltd. */ #include #include #include #include #include #include #include #include #include #include #include "lib.h" #include "parser.h" #include "policy_cache.h" #define le16_to_cpu(x) ((uint16_t)(le16toh (*(uint16_t *) x))) const char header_string[] = "\004\010\000version\000\002"; #define HEADER_STRING_SIZE 12 #define VERSION_STRING_SIZE 4 bool valid_cached_file_version(const char *cachename) { char buffer[HEADER_STRING_SIZE + VERSION_STRING_SIZE]; autofclose FILE *f; if (!(f = fopen(cachename, "r"))) { PERROR("Error: Could not read cache file '%s', skipping...\n", cachename); return false; } size_t res = fread(buffer, 1, HEADER_STRING_SIZE + VERSION_STRING_SIZE, f); if (res < HEADER_STRING_SIZE + VERSION_STRING_SIZE) { if (debug_cache) pwarn("%s: cache file '%s' invalid size\n", progname, cachename); return false; } /* 12 byte header that is always the same and then 4 byte version # */ if (memcmp(buffer, header_string, HEADER_STRING_SIZE) != 0) { if (debug_cache) pwarn("%s: cache file '%s' has wrong header\n", progname, cachename); return false; } uint32_t version = cpu_to_le32(ENCODE_VERSION(force_complain, policy_version, parser_abi_version, kernel_abi_version)); if (memcmp(buffer + HEADER_STRING_SIZE, &version, VERSION_STRING_SIZE) != 0) { if (debug_cache) pwarn("%s: cache file '%s' has wrong version\n", progname, cachename); return false; } return true; } void set_cache_tstamp(struct timespec t) { mru_skip_cache = 0; cache_tstamp = t; } void update_mru_tstamp(FILE *file, const char *name) { struct stat stat_file; if (fstat(fileno(file), &stat_file)) return; if (tstamp_cmp(mru_policy_tstamp, stat_file.st_mtim) < 0) /* keep track of the most recent policy tstamp */ mru_policy_tstamp = stat_file.st_mtim; if (tstamp_is_null(cache_tstamp)) return; if (tstamp_cmp(stat_file.st_mtim, cache_tstamp) > 0) { if (debug_cache) pwarn("%s: file '%s' is newer than cache file\n", progname, name); mru_skip_cache = 1; } } char *cache_filename(aa_policy_cache *pc, int dir, const char *basename) { char *cachename; autofree char *path; path = aa_policy_cache_dir_path(pc, dir); if (!path || asprintf(&cachename, "%s/%s", path, basename) < 0) { PERROR("Memory allocation error."); return NULL; } return cachename; } void valid_read_cache(const char *cachename) { struct stat stat_bin; /* Load a binary cache if it exists and is newest */ if (!skip_read_cache) { if (stat(cachename, &stat_bin) == 0 && stat_bin.st_size > 0) { if (valid_cached_file_version(cachename)) set_cache_tstamp(stat_bin.st_mtim); else if (!cond_clear_cache) write_cache = 0; } else { if (!cond_clear_cache) write_cache = 0; if (debug_cache) pwarn("%s: Invalid or missing cache file '%s' (%s)\n", progname, cachename, strerror(errno)); } } } int cache_hit(const char *cachename) { if (!mru_skip_cache) { if (show_cache) PERROR("Cache hit: %s\n", cachename); return true; } return false; } int setup_cache_tmp(const char **cachetmpname, const char *cachename) { char *tmpname; int cache_fd = -1; *cachetmpname = NULL; if (write_cache) { /* Otherwise, set up to save a cached copy */ if (asprintf(&tmpname, "%s-XXXXXX", cachename) < 0) { perror("asprintf"); return -1; } if ((cache_fd = mkstemp(tmpname)) < 0) { perror("mkstemp"); return -1; } *cachetmpname = tmpname; } return cache_fd; } void install_cache(const char *cachetmpname, const char *cachename) { /* Only install the generate cache file if it parsed correctly and did not have write/close errors */ if (cachetmpname) { struct timespec times[2]; /* set the mtime of the cache file to the most newest mtime * of policy files used to generate it */ times[0].tv_sec = 0; times[0].tv_nsec = UTIME_OMIT; times[1] = mru_policy_tstamp; if (utimensat(AT_FDCWD, cachetmpname, times, 0) < 0) { PERROR("%s: Failed to set the mtime of cache file '%s': %m\n", progname, cachename); unlink(cachetmpname); return; } if (rename(cachetmpname, cachename) < 0) { pwarn("Warning failed to write cache: %s\n", cachename); unlink(cachetmpname); } else if (show_cache) { PERROR("Wrote cache: %s\n", cachename); } } } apparmor-2.13.3/parser/subdomain.conf.50000644000175000017500000001372113502024374015504 0ustar jjjj.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "SUBDOMAIN.CONF 5" .TH SUBDOMAIN.CONF 5 "2019-06-17" "AppArmor 2.13.3" "AppArmor" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" /etc/apparmor/subdomain.conf \- configuration file for fine\-tuning the behavior of the AppArmor security tool. .SH "DESCRIPTION" .IX Header "DESCRIPTION" The AppArmor security tool can be configured to have certain default behaviors based on configuration options set in subdomain.conf. There are two variables that can be set in subdomain.conf: \fB\s-1SUBDOMAIN_PATH\s0\fR, and \fB\s-1SUBDOMAIN_MODULE_PANIC\s0\fR. .SS "\s-1SUBDOMAIN_PATH\s0" .IX Subsection "SUBDOMAIN_PATH" This variable accepts a string (path), and is by default set to \&'/etc/apparmor.d/' This variable defines where the AppArmor security tool looks for its policy definitions (a.k.a. AppArmor profiles). .SS "\s-1SUBDOMAIN_MODULE_PANIC\s0" .IX Subsection "SUBDOMAIN_MODULE_PANIC" This variable accepts a string that is one of four values: \fIwarn\fR, \&\fIbuild\fR, \fIpanic\fR, or \fIbuild-panic\fR, and is set by default to \fIwarn\fR. .PP This setting controls the behavior of the AppArmor initscript if it cannot successfully load the AppArmor kernel module on startup. The four possible settings are: .IP "\fIwarn\fR" 4 .IX Item "warn" Log a failure message (the default behavior). .IP "\fIbuild\fR" 4 .IX Item "build" Attempt to build the AppArmor module against the currently running kernel. If the compilation is successful, the module will be loaded and AppArmor started; if the compilation fails, a failure message is logged. .IP "\fIpanic\fR" 4 .IX Item "panic" Log a failure message and drop to runlevel 1 (single user). .IP "\fIbuild-panic\fR" 4 .IX Item "build-panic" Attempt to build the module against the running kernel (like \fIbuild\fR) and if the compilation fails, drop to runlevel 1 (single user). .SH "BUGS" .IX Header "BUGS" Setting the initscript to recompile the module will fail on \s-1SUSE,\s0 as the module source is no longer installed by default. However, the module has been included with the \s-1SUSE\s0 kernel, so no rebuilding should be necessary. .PP If you find any additional bugs, please report them at . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fIapparmor\fR\|(7), \fIapparmor_parser\fR\|(8), and . apparmor-2.13.3/parser/techdoc.tex0000644000175000017500000014301713502024172014642 0ustar jjjj\documentclass[a4paper]{article} %\usepackage{graphicx} %\usepackage{subfigure} \usepackage[utf8]{inputenc} \usepackage{url} %\usepackage{times} \usepackage[pdftex, pdfauthor={Andreas Gruenbacher and Seth Arnold}, pdftitle={AppArmor Technical Documentation},% \ifx\fixedpdfdate\@empty\else pdfcreationdate={\fixedpdfdate}, pdfmoddate={\fixedpdfdate}, \fi pdfsubject={AppArmor}, pdfkeywords={AppArmor} ]{hyperref} \hyphenation{App-Armor} \hyphenation{name-space} \renewcommand{\H}{\hspace{0pt}} \title{AppArmor Technical Documentation} \author{Andreas Gruenbacher and Seth Arnold \\ \url{{agruen,seth.arnold}@suse.de} \\ SUSE Labs / Novell} % don't include the (build!) date \date{} \begin{document} \maketitle \tableofcontents \newpage %\begin{abstract} %\end{abstract} \section{Introduction} In this paper we describe AppArmor from a technical point of view, introduce its concepts, and explain the design decisions taken. This text is intended for people interested in understanding why AppArmor works the way it does. You may be looking for less detailed, low-level, or kernel centric documentation; in that case, please refer to the AppArmor documentation web site~\cite{apparmor}. Sections~\ref{sec:overview} and ~\ref{sec:model} discuss the AppArmor security model, while Section~\ref{sec:walk-through} shows how to use it from a low-level point of view. Please be aware that lots of details are discussed here which the higher-level tools hide from the average user. \section{Overview} \label{sec:overview} AppArmor protects systems from insecure or untrusted processes by running them in confinement, still allowing them to share files with other parts of the system, exercising privilege, and communicating with other processes, but with some restrictions. These restrictions are mandatory; they are not bound to identity, group membership, or object ownership. In particular, the restrictions also apply to processes running with superuser privileges. AppArmor achieves this by plugging into the Linux Security Module (LSM) framework. The protections provided are in addition to the kernel's regular access control mechanisms. The AppArmor kernel module and accompanying user-space tools are available under the GPL license. (The exception is the libapparmor library, available under the LGPL license, which allows change\_hat(2) to be used by non-GPL binaries.) At the moment, AppArmor knows about two types of resources: files, and POSIX.1e (draft) capabilities. By controlling access to these resources, AppArmor can effectively prevent confined processes from accessing files in unwanted ways, from executing binaries which they are not meant to execute, and from exercising privileges such as acting on behalf of another user (which are traditionally restricted to the superuser). One use case for this kind of protection is a network daemon: even if the daemon is broken into, the additional restrictions imposed by AppArmor will prevent the attacker from attaining additional privileges beyond what the daemon is normally allowed to do. Because AppArmor controls which files a process can access in which ways down to the individual file level, the potential damage is much limited. There is work going on for teaching AppArmor about additional resources like ulimits, and interprocess and network communication, but at this time, these resource types are not covered. This is less severe than it might initially seem: in order to attack another process from a broken-into process like a network daemon, that other process has to actively listen. The set of actively listening processes is relatively small, and this sort of interprocess communication is a natural security boundary, so listening processes should be validating all their input already. For protection against bugs in the input validation of those processes, they should also be confined by AppArmor though, thus further limiting the potential damage. AppArmor protection is selective: it only confines processes for which policies (referred to as profiles) have been defined. All other processes will continue to run unrestricted by AppArmor. To confine a process, all it takes is to write a profile for it, take an existing profile, or automatically generate a profile: for the latter, the process can be run in \textit{learning} or \textit{complain} mode in which AppArmor allows all accesses, and logs all accesses that are not allowed by the current profile already. This log can then be used to automatically generate a suitable new profile, or refine an existing one. The application does not need to be modified. An example profile together with a complete low-level walk-through of AppArmor can be found in Section~\ref{sec:walk-through}. The apparmor.d(5) manual page contains further details. AppArmor is not based on labeling or label-based access and transition rules, so it does not stick a label on each each file in the file system (or more generally, on each object). It identifies files by name rather than by label, so if a process is granted read access to /etc/shadow and the system administrator renames /etc/shadow to /etc/shadow.old and replaces it with a copy (that may have an additional user in it, for example), the process will have access to the new /etc/shadow, and not to /etc/shadow.old. \section{The AppArmor Security Model} \label{sec:model} When a file is accessed by name with open(2), mkdir(2), etc., the kernel looks up the location of the object associated with the specified pathname in the file system hierarchy. The lookup is relative to the root directory for pathnames starting with a slash, and to the current working directory otherwise. Different processes can have have different working directories as well as different root directories. See path\_resolution(2) for a detailed discussion of how pathname resolution works. Either way, the result of the lookup is a pair of (dentry, vfsmount) kernel-internal objects that uniquely identify the location of the file in the file system hierarchy. The dentry points to the object if the object already exists, and is a placeholder for the object to be created otherwise. AppArmor uses the (dentry, vfsmount) pair to compute the pathname of the file within a process's filesystem namespace. The resulting pathname contains no relative pathname components (``.'' or ``..''), or symlinks. AppArmor checks if the current profile contains rules that match this pathname, and if those rules allow the requested access. Accesses that are not explicitly allowed are denied. \subsection{Symbolic Links} When looking up the (dentry, vfsmount) pair of a file, the kernel resolves symlinks where appropriate (and fails the lookup where symlink resolution is inappropriate). The pathname that AppArmor computes from a (dentry, vfsmount) pair never contains symlinks. This also means that if symlinks are used instead of directories for paths like /tmp, profiles need to be adjusted accordingly. A future version of AppArmor may have built-in support for this kind of pathname rewriting. \subsection{Namespaces} Linux allows different processes to live in separate namespaces, each of which forms an independent file system hierarchy. A recent paper by Al Viro and Ram Pai~\cite{ols06-pai} discusses all the intricate things possible with namespaces in recent 2.6 kernels. From the point of view of a process, an absolute path is a path that goes all the way up to the root directory of that process. This is ambiguous if processes have different root directories. Therefore, instead of paths relative to process root directories, AppArmor uses paths relative to the namespace root. Pathnames are meaningful only within a namespace. Each namespace has a root where all the files, directories, and mount points are hanging off from. The privilege of creating new namespaces is bound to the CAP\_{\H}SYS\_{\H}ADMIN capability, which grants a multitude of other things that would allow a process to break out of AppArmor confinement, so confined processes are not supposed to have this privilege, and processes with this capability need to be considered trusted. In this setup, privileged processes can still create separate namespaces and start processes in those namespaces; processes confinement will be relative to whatever namespace a process ends up in. It is unclear at this point how AppArmor should support separate namespaces --- either by computing all pathnames relative to one particular namespace considered global (assuming that such a globally meaningful namespace will exist in all setups in which AppArmor is relevant), or by allowing different sets of profiles to be associated with different namespaces. \subsection{Disconnected Files and Pseudo File Systems} In some situations, a process can end up with a file descriptor or working directory that was looked up by name at some point, but is not connected to the process's namespace anymore (and hasn't been deleted, either). This can happen when file descriptors are passed between processes that do not share the same namespace, or when a file system has been lazily unmounted (see the MNT\_DETACH flag of umount2(2)). Such files may still be visible to other processes, and they may become reconnected. AppArmor cannot compute the pathnames of such files. Granting unrestricted access would be insecure, and so AppArmor denies access to disconnected files. As a special case, the kernel supports a number of file systems that users can have file descriptors open for, but that can never be mounted. Those files are by definition disconnected. Anonymous pipes, futexes, inotify, and epoll are all examples of that. Accesses to those files is always allowed. Future versions of AppArmor will have better control over disconnected files by controlling file descriptor passing between processes. \subsection{Mount} Mounting can change a process's namespace in almost arbitrary ways. This is a problem because AppArmor's file access control is pathname based, and granting a process the right to arbitrarily change its namespace would subvert this protection mechanism. AppArmor therefore denies confined processes access to the mount(2), umount(2), and umount2(2) system calls. Future versions of AppArmor may offer fine-grained control over mount, and may grant confined processes specific mount operations. \subsection{The Kernel NFS Daemon} The security model of the various versions of NFS is that files are looked up by name as usual, but after that lookup, each file is only identified by a file handle in successive acesses. The file handle at a minimum includes some sort of filesystem identifier and the file's inode number. In Linux, the file handles used by most filesystems also include the inode number of the parent directory; this may change in the future. File handles are persistent across server restarts. This means that when the NFS daemon is presented with a file handle, clients must get access without having specified a pathname. A pathname can be computed from a (parent, child) inode pair that identifies the file down to the directory level if the dentry is properly connected to the dcache, but multiple hardlinks to the same file within the same directory cannot be distinguished, and properly connecting dentries comes at a cost in the NFS daemon. Because of this overhead and the questionable benefit, most setups do not guarantee that dentries will be connected, and so pathnames cannot always be computed. (See the no\_subtree\_check option in exports(5).) In addition, the NFS daemon is implemented in the kernel rather than as a user space process. There is no memory separation or other protection between the daemon and the rest of the kernel. This means that at best, the NFS daemon could cooperate with an additional access control mechanism like AppArmor --- but there would be no enforcement. Because of all of this, it makes little sense to put the kernel NFS daemon under AppArmor control. Administrators are advised to not assign profiles to the kernel nfsd daemons. \subsection{Why are the computed pathnames meaningful?} Whenever a process performs a name-based file access, the pathname or pathname component always refers to a specific path to that file: the path is either relative to the chroot if an absolute path is used, or else relative to the current working directory. The chroot or current working directory always has a unique pathname up to the namespace root (even if the process itself has no direct access above the chroot). This means that each name-based file access maps to a unique, canonical, absolute pathname. There may be additional paths pointing to the same file, but a particular name-based access still always refers to only one of them. These are the pathnames that AppArmor uses for permission checks. If directories along the path get renamed after a process changes into them (either with chroot(2) or with chdir(2)), the resulting pathname will differ from the pathnames that the process used. Consider the following sequence of operations for example: \begin{tabbing} \begin{tabular}{ll} \textbf{Process 1} & \textbf{Process 2} \\ chdir("/var/tmp/foo"); & \\ & rename("/var/tmp/foo", "/var/tmp/bar"); \\ creat("baz", 0666); & \\ \end{tabular} \end{tabbing} The creat operation will check against the path /var/tmp/\textit{bar}/baz, even though Process~1 never used \textit{bar.} This is the expected behavior; we are interested in the names of the objects along the path at the time of the access, not in their previous names. As already mentioned, a path lookup results in a pair of (dentry, vfsmount) kernel-internal objects. The pathname that AppArmor checks against is computed from these two objects after these objects have been looked up. The lookup and the pathname computation are not atomic, which means that pathname components could even be renamed after the lookup but before the pathname has been computed. It matters that the AppArmor access check is performed between the lookup and the actual access, but atomicity between the lookup and that access check is not necessary: there is no difference between a rename before the lookup and a rename after the lookup from AppArmor's point of view; all we care about is the current pathname at some point between the lookup and the access. A special case occurs when the lookup succeeds, but the file is deleted before the AppArmor access check. In this case the access is denied and errno is set to ENOENT, the same behavior as if the lookup had failed. \subsection{Path Permission Checking} On UNIX systems, when files are looked up by name, the lookup starts either at the root or the current working directory of a process. From there, each directory reached is checked for search permission (x). The permissions on the directories leading to the current working directory are not checked. When a file is being created or deleted, the parent directory of that file is checked for write and search access (wx). When a file is being accessed, the permissions of that file are checked for r, w, or x access, or a combination thereof. Each check can result in a failure with errno set to EACCES (Permission denied). In contrast, AppArmor first computes the pathname to a file. If a file is being created, the name being looked up is the name of the new file and not the name of the parent directory. If the file being looked up is a directory, AppArmor appends a slash to the pathname so that directory pathnames always end in a slash; otherwise the pathname will not end in a slash. It then checks for file access rules in the process's profile that match that pathname, and decides based on that. With some exceptions for execute modes as described in Section~\ref{sec:merging}, the permissions granted are the union of permissions of all matching rules. \subsection{Profile Permissions} \label{sec:permissions} AppArmor differentiates between slightly more permissions than UNIX does, as shown in Table~\ref{tab:permissions}: file access rules in AppArmor support the read (r), write (w), execute (x), memory map as executable (m), and link (l) permissions. The execute permission requires a modifier that further specifies which kind of execution is being granted: inherit the current profile (ix), use the profile defined for that executable (px), or execute unconfined without a profile (ux). In addition, the px and ux permissions have Px and Ux forms that will trigger Secure Execution (see Section~\ref{sec:secure-exec} below). The different permissions are used as follows: \begin{table}[tb] \center \begin{tabular}{|l|l|} \hline r & Read. \\ w & Write. \\ ix & Execute and inherit the current profile. \\ px & Execute under a specific profile. \\ Px & Execute secure and under a specific profile. \\ ux & Execute unconfined. \\ Ux & Execute secure and unconfined. \\ m & Memory map as executable. \\ l & Link. \\ \hline \end{tabular} \caption{File Access Permissions in Profiles} \label{tab:permissions} \end{table} \begin{description} \item[Read.] The profile read permission is required by all system calls that require the UNIX read permission. This includes open with O\_RDONLY, getdents (i.e., readdir), listxattr, getxattr, and mmap with PROT\_READ. \item[Write.] The profile write permission is required by all system calls that require the UNIX write permission, except for operations that create or remove files: while UNIX requires write access to the parent directory, AppArmor requires write access on the new file in this case (which does not exist at the time of the permission check for file creates). Operations that create files include open with O\_CREAT, creat, mkdir, symlink, and mknod. Operations that remove files include rename, unlink and rmdir. Operations that require write access in UNIX as well as AppArmor include open with O\_WRONLY (O\_RDWR requires read and write), setxattr, removexattr, and mmap with PROT\_WRITE. Other system calls such as chmod, chown, utime, and utimes are bound to file ownership or the respective capabilities in UNIX. AppArmor also requires profile write access for those operations. \item[Execute.] As mentioned above, AppArmor distinguishes a few different ways how files may be executed as described above. For directories, the UNIX execute permission maps to search access. AppArmor does not control directory search access. Traversing directories is always granted. \item[Memory map as executable.] The Linux kernel only requires read access to files in order to memory map them for execution with the PROT\_EXEC flag. AppArmor makes a distinction here, and requires the m profile permission in order for files to be mapped as executable. That way, it is more obvious in profiles what applications are allowed to do even if from a security point of view, the m permission provides a similar level of protection as the ix permission --- execute under the current profile. \item[Link.] Creating a hardlink requires the profile link permission (l) on the new path. In addition, the new path must have a subset of the r, w, x, and m permissions of the old path, and if the new path has the x permission, the execute flags (i, u, U, p, and P) of the old and the new path must be equal. \item[Rename.] A rename requires profile read and write access for the source file, and profile write access for the target file. \item[Stat.] Retrieving information about files is always allowed. We believe that providing policy for file information retrieval is more troublesome than the benefit it would provide. \end{description} \subsection{System Calls Taking File Handles, At System Calls} A number of system calls take file descriptors instead of pathnames as their parameters (ftruncate, fchmod, etc.), or take directory file descriptors, and resolve pathnames relative to those directories (openat, mkdirat, etc.). These system calls are treated like their non-f and non-at equivalents, and the same access checks are performed. At the point where AppArmor is asked to validate those file accesses, it is passed a (dentry, vfsmount) pair no matter which system call variant is used. \subsection{File Descriptor Passing and Revalidation} After a file descriptor has been obtained, the permitted accesses (read and/or write) are encoded in the file descriptor, and reads and writes are not revalidated against the profile for each access. This is consistent with how access checks are done in UNIX; such access checks would have a severe performance impact. The picture changes when a file descriptor is passed between processes and the other process is running under a different profile, or when a process switches profiles: in that case, read and write accesses are revalidated under the new profile. If the new profile does not allow them, the access is denied and errno is set to EACCES (Permission denied). File descriptors opened by unconfined processes are exempt from this rule. This is so that processes will still have access to their stdin, stdout, and stderr without having to list all possible sources of input and output in all profiles. \subsection{Deleted Files} Revalidation is problematic for deleted files for which a process still has an open file descriptor --- after all, the idea of the pathname of a deleted file is somewhat peculiar: the file is no longer reachable by any pathname, and it also cannot become re-attached to the filesystem namespace again. The traditional UNIX behavior is to determine access upon file access, and to never check again. Applications depend on this, particularly for temporary files. In addition to temporary files, deleted files can be used as an interprocess communication mechanism if the file descriptor is shared among multiple processes. AppArmor grants access to deleted files, just like it grants access to files opened by unconfined processes. It may control interprocess communication, including file descriptor passing, in a future version. \subsection{The access System Call} This system call determines whether a process has a given mode of access to a file in terms of the read, write, and execute permissions. This is not a sufficient replacement for performing the access check at the time of access even under traditional UNIX, because the access system call and the subsequent access are not atomic, and the permissions might change between the two operations. Applications are not supposed to rely on access(2). AppArmor introduces additional restrictions, some of which cannot be modeled in terms of read, write, and execute: for example, an AppArmor profile may allow a process to create files /tmp/foo-*, but not any other files in /tmp. There is no way to express this with access(2); in traditional UNIX, all that is required for creating files is write access to the parent directory. Access(2) will indicate that some accesses are allowed even when AppArmor will eventually deny them. \subsection{The ptrace System Call} The ability to ptrace allows a process to look up information about another process, read and write the memory of that process, and attach to (or trace) that process in order to debug it, or analyze its behavior. This gives total control over the process being traced, and so the kernel employs some restrictions over which processes may ptrace with other processes. In addition to these restrictions, AppArmor requires that if the tracing task is confined, it must either have the CAP\_{\H}SYS\_{\H}PTRACE capability, or be confined by the same profile and sub-profile as the process being traced. Attempts to switch to another profile or sub-profile by a process being traced is denied. \subsection{Secure Execution} \label{sec:secure-exec} In this mode, the kernel passes a flag to user space. When glibc finds this flag set, it unsets environment variables that are considered dangerous, and it prevents the dynamic loader from loading libraries controlled by the environment. With non-secure exec, the LD\_LIBRARY\_PATH environment variable can be used to switch to a different set of libraries, for example. The secure exec mechanism is not specific to AppArmor: set-user-id and set-group-id executables also use it, as well as SELinux, which introduced this glibc feature. \subsection{Exec Mode Merging in Profiles, Exact Matches} \label{sec:merging} When more than one rule in a profile matches a given path, all the permissions accumulate except for ix, px, Px, ux, and Ux: those permissions would conflict with each other; it would be unclear how to execute the new binary if more than one of these flags was set. To deal with this situation, AppArmor differentiates between rules that define exact matches and wildcard rules (see Table~\ref{tab:globbing} on page~\pageref{tab:globbing}). Execute flags in exact matches override execute flags in wildcard matches. If the execute flags of multiple rules still disagree, the profile is rejected at profile load time. \subsection{Capabilities} AppArmor uses the standard Linux capability mechanism. When the kernel checks if a certain capability can be exercised, AppArmor additionally checks if the current profile allows the requested capability, and rejects the use of the capability otherwise. \subsection{The sysctl System Call and /proc/sys} The sysctl system call and files below /proc/sys can be used to read and modify various kernel parameters. Root processes can easily bring the system down by setting kernel parameters to invalid values. To prevent against that, AppArmor denies confined processes that do not have the CAP\_{\H}SYS\_{\H}ADMIN capability write access to kernel parameters. \subsection{Subprofiles aka. Hats} Profiles can contain subprofiles that processes may switch to from the main profile. Switching from a subprofile into a sibling subprofile or back to the parent profile is allowed depending on how the subprofile was entered, and provided that the child knows a magic cookie.\footnote{ \textbf{A word of warning about change\_hat(2):} When used with a non-zero magic cookie for changing into a subprofile, that magic cookie can be used to change back out of the subprofile; in this mode, change\_hat(2) is not a strong confinement mechanism. If the code running in the subprofile can guess the magic cookie, it can break out of the subprofile. Likewise, if that code can manipulate the processes' behavior beyond the point where the process returns from the subprofile, it can influence what is done under the parent profile. Therefore, change\_hat(2) with a non-zero magic cookie is only safe in combination with restricted code environments, such as when the subprofile is used for executing Safe Perl (see Safe(3pm)), etc. } See the change\_hat(2) manual page for details. Each process may consist of multiple tasks. Each task may only change its own subprofile. The superuser cannot put a task into a different hat, but he can replace the entire profile and its subprofiles, or he can put a process in a different top-level profile (see Section~\ref{sec:association}). Internally, change\_hat(2) is implemented by writing to a special kernel-provided file. This is equivalent to a command like: \begin{small} \begin{verbatim} $ echo "changehat 123^hat_name" > /proc/$PID/attr/current \end{verbatim} \end{small} Here, the number is the magic cookie value, and hat\_name obviously is the name of the hat; either may be replaced by the empty string (but not both). \subsection{Association of Profiles with Processes} \label{sec:association} Profiles are associated with kernel tasks, which roughly correspond to threads in user space (see clone(2) for details). Currently there are two ways how a profile can be associated with a task: when an executable is started and a profile is defined for that executable, or when the administrator assigns a profile to a task explicitly. In addition to that, once a task is confined by a profile, that profile determines which other executables may be executed, and under which profile they may run (under the profile defined for that executable, the same profile as the current task, or unconfined; see Section~\ref{sec:permissions}). A process will consist of a single task after an exec, so in the exec case, the entire process will be confined. New tasks (threads as well as processes) inherit the same profile and subprofile as their parent task. Unconfined processes with the CAP\_{\H}SYS\_{\H}ADMIN privilege may assign a profile to a task with a command like this: \begin{small} \begin{verbatim} $ echo "setprofile /name/of/profile" > \ /proc/$PID/attr/current \end{verbatim} \end{small} After that, the task will be in the new top-level profile, even if the process was in a subprofile before. Processes with the CAP\_{\H}SYS\_{\H}ADMIN privilege as well as the process itself can query the profile a process is in by reading from that file: \begin{small} \begin{verbatim} $ cat /proc/$PID/attr/current unconfined $ cat /proc/$PID/attr/current /name/of/profile (complain) $ cat /proc/$PID/attr/current /name/of/profile^hat_name (enforce) \end{verbatim} \end{small} The output includes the name of the profile and subprofile as well as the mode the active profile is in. (When a task is in a subprofile, the subprofile is the active profile.) \subsection{Profile Loading, Replacement, and Removal} Before the kernel can use any profiles, they must be loaded. The profile sources consist of plain text. This text representation is converted into in a binary representation that the kernel can more easily deal with by the user-space profile loader. Profiles contain potentially long lists of file access rules that may include wildcards. In order to make the lookup efficient, the AppArmor kernel module does not actually go through all the file access rules when checking for access. Instead, the profile loader takes those rules and compiles them into transition tables. Pathnames are then looked up in those tables with a simple and efficient algorithm, the theory behind which is explained in the Lexical Analysis section of the Dragon Book~\cite{dragon86}. An init script loads all the known profiles into the kernel at an early boot stage. This happens automatically and the system administrator tools will take care of loading, reloading, or removing profiles after they manipulate them, so end users will not usually notice this step. Profiles can be replaced at any time during runtime, and all processes running under old profiles will transparently be switched to the updated versions. Profiles can also be removed. All processes running under a profile that is removed will become unconfined. Profiles are always replaced together with all their subprofiles. It may be that an updated profile no longer contains a specific subprofile. If that happens while processes are using that subprofile, those processes will be put in a profile that denies all accesses. Such processes may still change to sibling subprofiles or back to the parent profile subject to the change\_hat(2) semantics. \section{AppArmor Walk-Through} \label{sec:walk-through} AppArmor consists of a set of kernel patches and accompanying user-space tools, both of which are available at \url{http://developer.novell.com/wiki/index.php/Apparmor}. \subsection{Kernel Patches and Configuration} The AppArmor kernel patches are provided in a format convenient for use with quilt,\footnote{ \url{http://savannah.nongnu.org/projects/quilt} } however, other tools for applying the patches can be used, too. The patches are supposed to apply against recent kernel.org git kernels. A copy of the current git tree can be obtained from \url{git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git} with \textit{git clone} (see the \hbox{git-clone(1)} manual page). In case the the differences between the latest git tree and the tree the AppArmor patches are based on is too big, the patches won't apply cleanly. In this case, trying an older git tree may work better. After obtaining the AppArmor patches tarball and the git tree which will end up in the linux-2.6 directory by default, the AppArmor patches can be applied to the git tree as follows: \begin{small} \begin{verbatim} $ tar zxvf apparmor.tar.gz $ cd linux-2.6/ $ ln -s ../apparmor patches $ quilt push -a \end{verbatim} \end{small} When configuring the kernel, make sure that AppArmor is built in or as a module (CONFIG\_{\H}SECURITY\_{\H}APPARMOR must be 'y' or 'm'). AppArmor cannot be used together with other Linux Security Modules, so if CONFIG\_{\H}SECURITY\_{\H}CAPABILITIES or CONFIG\_{\H}SECURITY\_{\H}SELINUX is set to 'y', they must be disabled by adding \texttt{selinux=0} and/or \texttt{capability.disable=1} to the kernel command line (grub, lilo, yaboot, etc.). It is not sufficient to put SELinux into permissive mode --- at this time, AppArmor cannot be combined with other LSMs. \subsection{The securityfs file system} AppArmor uses securityfs for configuration and to report information. The usual mountpoint for securityfs is /sys/{\H}kernel/{\H}security. Unless your distribution automatically does so, you can mount securityfs with: \begin{small} \begin{verbatim} $ mount securityfs -t securityfs /sys/kernel/security \end{verbatim} \end{small} Once securityfs has been mounted and the apparmor module loaded, /sys/{\H}kernel/{\H}security/{\H}apparmor/{\H}profiles will show the profiles loaded into the kernel, as well as mark if the profiles are in enforcement mode or in learning mode: \begin{small} \begin{verbatim} $ cat /sys/kernel/security/apparmor/profiles /usr/bin/opera (complain) /usr/lib/firefox/firefox.sh (complain) /sbin/lspci (enforce) ... \end{verbatim} \end{small} Profile loading, replacement, and unloading, as well as configuration of AppArmor is also done via securityfs. %/sys/kernel/security/apparmor/control/ control seldom-used features of AppArmor: % audit if '1', audit all actions by confined processes % complain if '1', allow all actions by confined processes, report % accesses not granted by policy % debug if '1', emit copius debugging % logsyscall if '1', use audit framework's syscall debugging, if audit % has been instructed to create per-task contexts.[2] \subsection{Profile Loading} Profile loading, replacement, and removal is performed by the apparmor\_parser utility from the apparmor-parser package. The package can easily be built by running make in the package's top-level directory. Once that is done and the AppArmor module loaded, you may use the parser to load profiles with: \begin{small} \begin{verbatim} $ echo "/tmp/ls { /tmp/ls rm, }" | apparmor_parser \end{verbatim} \end{small} Once a profile for a program has been loaded into the kernel, you must use the --replace option for replacing the existing profile with a new one (this option may be used even if no profile by that name exists): \begin{small} \begin{verbatim} $ echo "/tmp/ls { /tmp/ls rm, }" | apparmor_parser --replace \end{verbatim} \end{small} \subsection{Anatomy of a Profile} AppArmor profiles use a simple declaritive language, fully described in the apparmor.d(5) manual page. By convention, profiles are stored in /etc/{\H}apparmor.d/. The AppArmor parser supports a simple cpp-style include mechanism to allow sharing pieces of policy. A simple profile looks like this: \begin{small} \begin{verbatim} /bin/ls flags=(complain) { /bin/ls rm, /lib/ld-2.5.so rmix, /etc/ld.so.cache rm, /lib/lib*.so* rm, /dev/pts/* w, /proc/meminfo r, /var/run/nscd/socket w, /var/run/nscd/passwd r, /var/run/nscd/group r, /tmp/ r, } \end{verbatim} \end{small} Here, the first /bin/ls is the name of the profile. This profile will be automatically used whenever an unconfined process executes /bin/ls. The flags instruct AppArmor to put the profile in complain (aka. learning) mode: in this mode, all operations are allowed, and any events that would have been denied are logged. This helps users to incrementally deploy AppArmor in production environments. The default if no flags are specified is enforcement mode, in which all operations not allowed by the profile are logged and denied. Complain mode can be enabled individually for profiles as shown above (followed by reloading the profile), or by globally putting all profiles in complain mode with: \begin{small} \begin{verbatim} $ echo 1 > /sys/kernel/security/apparmor/control/complain \end{verbatim} \end{small} The user-space tools also include two small utilities, enforce and complain, which will put profiles into enforce or complain mode: \begin{small} \begin{verbatim} $ enforce firefox Setting /usr/lib/firefox/firefox.sh to enforce mode. \end{verbatim} \end{small} Inside the body of the profile are any number of rules consisting of a pathname expression that may include globbing, and a set of permissions. Table~\ref{tab:globbing} shows the supported shell-inspired globbing constructs; Section~\ref{sec:permissions} on page~\pageref{sec:permissions} describes the permissions. \begin{table}[tb] \center \begin{tabular}{|l|l|} \hline {?} & Any single character except ``/''. \\ {*} & Any number of characters except ``/''. \\ {**} & Any number of characters including ``/''. \\ {[ab]} & One of ``a'' or ``b''. \\ {[a-c]} & One of ``a'', ``b'', or ``c''. \\ \{ab,cd\} & Alternation: either ``ab'' or ``cd''. \\ \hline \end{tabular} \caption{Globbing in File Access Rules. Alternation counts as an exact match in file access rules; all others count as wildcards (see Section~\ref{sec:merging}).} \label{tab:globbing} \end{table} When AppArmor looks up a directory the pathname being looked up will end with a slash (e.g., /var/tmp/), otherwise it will not. Only rules that match that trailing slash will match directories. Some examples, none matching the /tmp directory itself, are: \begin{tabbing} \begin{tabular}{ll} {/tmp/*} & Files directly in /tmp. \\ {/tmp/*/} & Directories directly in /tmp. \\ {/tmp/**} & Files and directories anywhere underneath /tmp. \\ {/tmp/**/} & Directories anywhere underneath /tmp. \\ \end{tabular} \end{tabbing} As explained in Section~\ref{sec:model}, AppArmor does not require execute access to allow directory traversal, or write access on a directory to create or rename files inside the directory. Instead, write access is required on the specific files that a confined process attempts to create, remove, rename, etc. Read access is required for reading the contents of a directory. AppArmor also mediates the use of POSIX 1003.1e draft capabilities; capabilities that a process is allowed to use are listed in the profile by their name in lower-case (with ``CAP\_'' stripped off), e.g., \begin{small} \begin{verbatim} #include /sbin/lspci { #include #include capability sys_admin, /sbin/lspci mr, /sys/bus/pci/ r, /sys/bus/pci/devices/ r, /sys/devices/** r, /usr/share/pci.ids r, } \end{verbatim} \end{small} This profile uses predefined include files which are part of the apparmor-profiles package. \subsection{Logging} AppArmor uses the kernel standard audit facility for reporting. When a profile is in complain mode, the log messages look like this: \begin{small} \begin{verbatim} type=APPARMOR msg=audit(1174506429.573:1789): PERMITTING r access to /home/sarnold/ (ls(16504) profile /tmp/ls active /tmp/ls) \end{verbatim} \end{small} When a profile is in enforcement mode, the log messages look like this: \begin{small} \begin{verbatim} type=APPARMOR msg=audit(1174508205.298:1791): REJECTING r access to /bin/ (ls(16552) profile /tmp/ls active /tmp/ls) \end{verbatim} \end{small} These log messages are sent to the kernel auditing facility; if auditd is not running, the kernel will forward these messages to printk for collection by klogd. Auditd must be configured with --with-apparmor to enable the \#defines to handle AppArmor's message type correctly. AppArmor also logs some important events in the process lifecycle, such as when processes in learning mode fork and change domain via exec. These other events, while not strictly related to permissions requested by the process, help the genprof profile generation tool reconstruct when specific accesses are required by processes --- this allows the tool to make more relevant and meaningful policy suggestions. \subsection{Generating Profiles By Hand} While the majority of our users are expected to generate profiles with the help of our profile tools, it is possible to write policy by hand. This final section gives a very quick walkthrough generating a simple profile for firefox. Since the kernel resolves symlinks to their ``final destinations'' before presenting AppArmor with policy questions, we first must see if /usr/{\H}bin/{\H}firefox is a symlink or the shell script that starts firefox; on our system, it is a symlink: \begin{small} \begin{verbatim} $ ls -l /usr/bin/firefox lrwxrwxrwx 1 root root 25 Mar 21 13:36 /usr/bin/firefox -> ../lib/firefox/firefox.sh \end{verbatim} \end{small} So we will start a profile for /usr/{\H}lib/{\H}firefox/{\H}firefox.sh. This shell script will execute firefox-bin, as we will see later; when it does so, we will tell AppArmor to inherit this profile. Thus, firefox-bin will be executing under the profile for /usr/{\H}lib/{\H}firefox/{\H}firefox.sh. To get started, we can make some assumptions about the privileges that firefox will need (both as a shell script and as a fairly complex GUI application): \begin{small} \begin{verbatim} $ cat /etc/apparmor.d/usr.lib.firefox.firefox.sh /usr/lib/firefox/firefox.sh flags=(complain) { /usr/lib/firefox/firefox.sh r, /bin/bash rmix, /lib/ld-2.5.so rmix, /etc/ld.so.cache rm, /lib/lib*.so* rm, /usr/lib/lib*.so* rm, } $ apparmor_parser --reload < \ /etc/apparmor.d/usr.lib.firefox.firefox.sh Replacement succeeded for "/usr/lib/firefox/firefox.sh". \end{verbatim} \end{small} The easiest way to see what accesses AppArmor allows, start a tail -F /var/{\H}log/{\H}audit/{\H}audit.log (or /var/{\H}log/{\H}messages, or wherever your audit messages are being sent). In another terminal, start firefox. tail will show a few hundred PERMITTING audit events like these: \begin{small} \begin{verbatim} type=APPARMOR msg=audit(1174512269.026:1804): PERMITTING rw access to /dev/tty (firefox(16950) profile /usr/lib/firefox/firefox.sh active /usr/lib/firefox/firefox.sh) type=APPARMOR msg=audit(1174512269.026:1805): PERMITTING r access to /usr/share/locale/locale.alias (firefox(16950) profile /usr/lib/firefox/firefox.sh active /usr/lib/firefox/firefox.sh) type=APPARMOR msg=audit(1174512269.026:1806): PERMITTING r access to /usr/lib/locale/en_US.utf8/LC_IDENTIFICATION (firefox(16950) profile /usr/lib/firefox/firefox.sh active /usr/lib/firefox/firefox.sh) \end{verbatim} \end{small} Because we want this profile to be fairly simple we'll be fairly permissive, add a few more rules to the profile and reload: \begin{small} \begin{verbatim} /dev/tty rw, /usr/share/locale/** r, /usr/lib/locale/** r, \end{verbatim} \end{small} Now re-run firefox. There is no need to handle all log entries at once. In complain mode, AppArmor will only report accesses that are not in the profile. This makes it fairly easy to add a few rules and re-run the application to determine what privileges are still necessary. We get a few more messages: \begin{small} \begin{verbatim} type=APPARMOR msg=audit(1174512791.236:5356): PERMITTING r access to /usr/lib/gconv/gconv-modules.cache (firefox(17031) profile /usr/lib/firefox/firefox.sh active /usr/lib/firefox/firefox.sh) type=APPARMOR msg=audit(1174512791.236:5357): PERMITTING r access to /proc/meminfo (firefox(17031) profile /usr/lib/firefox/firefox.sh active /usr/lib/firefox/firefox.sh) type=APPARMOR msg=audit(1174512791.240:5358): PERMITTING x access to /bin/basename (firefox(17032) profile /usr/lib/firefox/firefox.sh active /usr/lib/firefox/firefox.sh) type=APPARMOR msg=audit(1174512791.240:5359): LOGPROF-HINT changing_profile pid=17032 type=APPARMOR msg=audit(1174512791.240:5360): PERMITTING r access to /bin/basename (firefox(17032) profile null-complain-profile active null-complain-profile) ... type=APPARMOR msg=audit(1174512791.240:5364): PERMITTING mr access to /bin/basename (basename(17032) profile null-complain-profile active null-complain-profile) \end{verbatim} \end{small} So now, we add a few more rules: \begin{small} \begin{verbatim} /usr/lib/gconv/** r, /proc/meminfo r, /bin/basename rmix, \end{verbatim} \end{small} We selected ``rmix'' for /bin/basename --- most small shell utilities should not have a profile for themselves. There's nothing wrong with giving basename a profile, but the value of such a profile would be very limited. Giving other shell utilities their own profiles would be worse: the profile would need read access to the whole filesystem for shell scripts to function reliably. In our case, basename simply inherits privileges from another profile, then it has no more and no fewer privileges than the calling program --- which is often a fine tradeoff. The loader will need r and m access to execute basename, and we use ix to execute basename in the same profile. The kernel logs only reported r, m and x access; we have to choose the execute mode ourselves. Again, the standard user tools would prompt users for this decision and give consequences of decisions. We continue in this fashion, iteratively adding and changing rules as needed by the logs. Some of the logs report attribute modifications, such as: \begin{small} \begin{verbatim} type=APPARMOR msg=audit(1174519157.851:10357): PERMITTING attribute (mode,ctime,) change to /home/sarnold/.gnome2_private/ (firefox-bin(17338) profile /usr/lib/firefox/firefox.sh active /usr/lib/firefox/firefox.sh) \end{verbatim} \end{small} These need to be represented in the profile with simple w access. \begin{small} \begin{verbatim} /home/*/.gnome2_private/ w, \end{verbatim} \end{small} After nine iterations, the profile looks like this --- we have inserted blank lines between each iteration: \begin{small} \begin{verbatim} /usr/lib/firefox/firefox.sh flags=(complain) { /usr/lib/firefox/firefox.sh r, /bin/bash rmix, /lib/ld-2.5.so rmix, /etc/ld.so.cache rm, /lib/lib*.so* rm, /usr/lib/lib*.so* rm, /dev/tty rw, /usr/share/locale/** r, /usr/lib/locale/** r, /usr/lib/gconv/** r, /proc/meminfo r, /bin/basename rmix, /usr/bin/file rmix, /etc/magic r, /usr/share/misc/magic.mgc r, /bin/gawk rmix, /usr/lib/firefox/firefox-bin rmix, /usr/lib/firefox/lib*so rm, /opt/gnome/lib/lib*so* rm, /usr/share/X11/locale/* r, /var/run/nscd/socket w, /var/run/nscd/passwd r, /usr/share/X11/locale/** r, /home/*/.Xauthority r, /usr/lib/gconv/*so m, /home/*/.mozilla/** rw, /etc/resolv.conf r, /usr/lib/firefox/**.so rm, /usr/lib/firefox/** r, /etc/opt/gnome/** r, /var/run/dbus/system_bus_socket w, /etc/localtime r, /opt/gnome/lib/**.so rm, /var/cache/libx11/compose/* r, /tmp/orbit-*/ w, /dev/urandom r, /tmp/ r, /dev/null rw, /opt/gnome/lib/GConf/2/gconfd-2 rmix, /dev/log w, /tmp/orbit-*/* w, /tmp/gconfd-*/ r, /tmp/gconfd-*/** rwl, /home/*/.gconf/ r, /home/*/.gconf/* rw, /etc/fonts/** r, /var/cache/fontconfig/* r, /home/*/.fontconfig/** r, /usr/share/ghostscript/fonts/** r, /etc/passwd r, /var/tmp/ r, /bin/netstat rmix, /home/*/.gnome2_private/ w, /home/*/.gconfd/* rw, /proc/net/ r, /proc/net/* r, /usr/share/fonts/** r, /usr/lib/browser-plugins/ r, /usr/lib/browser-plugins/** rm, } \end{verbatim} \end{small} Sorting the entries in the profile can help show areas that can be collapsed with even more generic rules. After doing that and making a few rules slightly more generic, we end up with: \begin{small} \begin{verbatim} /usr/lib/firefox/firefox.sh { /bin/basename rmix, /bin/bash rmix, /bin/gawk rmix, /bin/netstat rmix, /dev/log w, /dev/null rw, /dev/tty rw, /dev/urandom r, /etc/fonts/** r, /etc/ld.so.cache rm, /etc/localtime r, /etc/magic r, /etc/opt/gnome/** r, /etc/passwd r, /etc/resolv.conf r, /home/*/.fontconfig/** r, /home/*/.gconfd/* rw, /home/*/.gconf/ r, /home/*/.gconf/* rw, /home/*/.gnome2_private/ w, /home/*/.mozilla/** rw, /home/*/.Xauthority r, /lib/ld-2.5.so rmix, /lib/lib*.so* rm, /opt/gnome/lib/GConf/2/gconfd-2 rmix, /opt/gnome/lib/**.so* rm, /proc/meminfo r, /proc/net/ r, /proc/net/* r, /tmp/gconfd-*/ r, /tmp/gconfd-*/** rwl, /tmp/orbit-*/ w, /tmp/orbit-*/* w, /tmp/ r, /usr/bin/file rmix, /usr/lib/browser-plugins/ r, /usr/lib/browser-plugins/** rm, /usr/lib/firefox/firefox-bin rmix, /usr/lib/firefox/firefox.sh r, /usr/lib/firefox/** r, /usr/lib/firefox/**.so rm, /usr/lib/gconv/** r, /usr/lib/gconv/*so m, /usr/lib/lib*.so* rm, /usr/lib/locale/** r, /usr/share/** r, /var/cache/fontconfig/* r, /var/cache/libx11/compose/* r, /var/run/dbus/system_bus_socket w, /var/run/nscd/passwd r, /var/run/nscd/socket w, /var/tmp/ r, } \end{verbatim} \end{small} \begin{thebibliography}{XX} \bibitem{apparmor} AppArmor documentation, \url{http://www.novell.com/documentation/apparmor/} \bibitem{ols06-pai} Al Viro and Ram Pai: {\em Shared-Subtree Concept, Implementation and Applications in Linux,} Ottawa Linux Symposium, July 19-22, 2006, \url{http://www.linuxsymposium.org/2006/} \bibitem{dragon86} Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman: {\em Compilers: Principles, Techniques, and Tools} (The ``Dragon Book''), Addison-Wesley, 1986, ISBN 0-201-10088-6. A second edition of this classic is available since August 2006 as ISBN 0-321-48681-1. \end{thebibliography} \end{document} % vim:textwidth=72 apparmor-2.13.3/parser/common_optarg.c0000644000175000017500000001325113502024172015513 0ustar jjjj/* * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 * NOVELL (All rights reserved) * * Copyright (c) 2010 - 2014 * Canonical Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical, * Ltd. */ #include #include #include #include #include "common_optarg.h" #include "parser.h" optflag_table_t dumpflag_table[] = { { 1, "rule-exprs", "Dump rule to expr tree conversions", DFA_DUMP_RULE_EXPR }, { 1, "expr-stats", "Dump stats on expr tree", DFA_DUMP_TREE_STATS }, { 1, "expr-tree", "Dump expression tree", DFA_DUMP_TREE }, { 1, "expr-simplified", "Dump simplified expression tree", DFA_DUMP_SIMPLE_TREE }, { 1, "stats", "Dump all compile stats", DFA_DUMP_TREE_STATS | DFA_DUMP_STATS | DFA_DUMP_TRANS_STATS | DFA_DUMP_EQUIV_STATS | DFA_DUMP_DIFF_STATS }, { 1, "progress", "Dump progress for all compile phases", DFA_DUMP_PROGRESS | DFA_DUMP_STATS | DFA_DUMP_TRANS_PROGRESS | DFA_DUMP_TRANS_STATS | DFA_DUMP_DIFF_PROGRESS | DFA_DUMP_DIFF_STATS }, { 1, "dfa-progress", "Dump dfa creation as in progress", DFA_DUMP_PROGRESS | DFA_DUMP_STATS }, { 1, "dfa-stats", "Dump dfa creation stats", DFA_DUMP_STATS }, { 1, "dfa-states", "Dump dfa state diagram", DFA_DUMP_STATES }, { 1, "dfa-graph", "Dump dfa dot (graphviz) graph", DFA_DUMP_GRAPH }, { 1, "dfa-minimize", "Dump dfa minimization", DFA_DUMP_MINIMIZE }, { 1, "dfa-unreachable", "Dump dfa unreachable states", DFA_DUMP_UNREACHABLE }, { 1, "dfa-node-map", "Dump expr node set to state mapping", DFA_DUMP_NODE_TO_DFA }, { 1, "dfa-uniq-perms", "Dump unique perms", DFA_DUMP_UNIQ_PERMS }, { 1, "dfa-minimize-uniq-perms", "Dump unique perms post minimization", DFA_DUMP_MIN_UNIQ_PERMS }, { 1, "dfa-minimize-partitions", "Dump dfa minimization partitions", DFA_DUMP_MIN_PARTS }, { 1, "compress-progress", "Dump progress of compression", DFA_DUMP_TRANS_PROGRESS | DFA_DUMP_TRANS_STATS }, { 1, "compress-stats", "Dump stats on compression", DFA_DUMP_TRANS_STATS }, { 1, "compressed-dfa", "Dump compressed dfa", DFA_DUMP_TRANS_TABLE }, { 1, "equiv-stats", "Dump equivalence class stats", DFA_DUMP_EQUIV_STATS }, { 1, "equiv", "Dump equivalence class", DFA_DUMP_EQUIV }, { 1, "diff-encode", "Dump differential encoding", DFA_DUMP_DIFF_ENCODE }, { 1, "diff-stats", "Dump differential encoding stats", DFA_DUMP_DIFF_STATS }, { 1, "diff-progress", "Dump progress of differential encoding", DFA_DUMP_DIFF_PROGRESS | DFA_DUMP_DIFF_STATS }, { 0, NULL, NULL, 0 }, }; optflag_table_t optflag_table[] = { { 2, "0", "no optimizations", DFA_CONTROL_TREE_NORMAL | DFA_CONTROL_TREE_SIMPLE | DFA_CONTROL_MINIMIZE | DFA_CONTROL_REMOVE_UNREACHABLE | DFA_CONTROL_DIFF_ENCODE }, { 1, "equiv", "use equivalent classes", DFA_CONTROL_EQUIV }, { 1, "expr-normalize", "expression tree normalization", DFA_CONTROL_TREE_NORMAL }, { 1, "expr-simplify", "expression tree simplification", DFA_CONTROL_TREE_SIMPLE }, { 0, "expr-left-simplify", "left simplification first", DFA_CONTROL_TREE_LEFT }, { 2, "expr-right-simplify", "right simplification first", DFA_CONTROL_TREE_LEFT }, { 1, "minimize", "dfa state minimization", DFA_CONTROL_MINIMIZE }, { 1, "filter-deny", "filter out deny information from final dfa", DFA_CONTROL_FILTER_DENY }, { 1, "remove-unreachable", "dfa unreachable state removal", DFA_CONTROL_REMOVE_UNREACHABLE }, { 0, "compress-small", "do slower dfa transition table compression", DFA_CONTROL_TRANS_HIGH }, { 2, "compress-fast", "do faster dfa transition table compression", DFA_CONTROL_TRANS_HIGH }, { 1, "diff-encode", "Differentially encode transitions", DFA_CONTROL_DIFF_ENCODE }, { 0, NULL, NULL, 0 }, }; void print_flag_table(optflag_table_t *table) { int i; unsigned int longest = 0; for (i = 0; table[i].option; i++) { if (strlen(table[i].option) > longest) longest = strlen(table[i].option); } for (i = 0; table[i].option; i++) { printf("%5s%-*s \t%s\n", (table[i].control & 1) ? "[no-]" : "", longest, table[i].option, table[i].desc); } } int handle_flag_table(optflag_table_t *table, const char *optarg, dfaflags_t *flags) { const char *arg = optarg; int i, invert = 0; if (strncmp(optarg, "no-", 3) == 0) { arg = optarg + 3; invert = 1; } for (i = 0; table[i].option; i++) { if (strcmp(table[i].option, arg) == 0) { /* check if leading no- was specified but is not * supported by the option */ if (invert && !(table[i].control & 1)) return 0; if (table[i].control & 2) invert |= 1; if (invert) *flags &= ~table[i].flags; else *flags |= table[i].flags; return 1; } } return 0; } void display_dump(const char *command) { display_version(); printf("\n%s: --dump [Option]\n\n" "Options:\n" "--------\n" " variables \tDump variables\n" " expanded-variables\t Dump variables after expansion\n" ,command); print_flag_table(dumpflag_table); } void display_optimize(const char *command) { display_version(); printf("\n%s: -O [Option]\n\n" "Options:\n" "--------\n" ,command); print_flag_table(optflag_table); } apparmor-2.13.3/parser/parser.h0000644000175000017500000003141413502024172014151 0ustar jjjj/* * Copyright (c) 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007 * NOVELL (All rights reserved) * * Copyright (c) 2010 - 2012 * Canonical Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical * Ltd. */ #ifndef __AA_PARSER_H #define __AA_PARSER_H #include #include #include #include #define _(s) gettext(s) #include #include "immunix.h" #include "libapparmor_re/apparmor_re.h" #include "libapparmor_re/aare_rules.h" #include using namespace std; #include class Profile; class rule_t; #define MODULE_NAME "apparmor" /* Global variable to pass token to lexer. Will be replaced by parameter * when lexer and parser are made reentrant */ extern int parser_token; #define WARN_RULE_NOT_ENFORCED 1 #define WARN_RULE_DOWNGRADED 2 extern dfaflags_t warnflags; typedef enum pattern_t pattern_t; struct prefixes { int audit; int deny; int owner; }; struct cod_pattern { char *regex; // posix regex }; struct value_list { char *value; struct value_list *next; }; struct cond_entry { char *name; int eq; /* where equals was used in specifying list */ struct value_list *vals; struct cond_entry *next; }; struct cond_entry_list { char *name; struct cond_entry *list; }; struct cod_entry { char *name; union { char *link_name; char *onexec; }; char *nt_name; Profile *prof; /* Special profile defined * just for this executable */ int mode; /* mode is 'or' of AA_* bits */ int audit; /* audit flags for mode */ int deny; /* TRUE or FALSE */ int alias_ignore; /* ignore for alias processing */ int subset; pattern_t pattern_type; struct cod_pattern pat; struct cod_entry *next; }; struct aa_rlimits { unsigned int specified; /* limits that are set */ rlim_t limits[RLIMIT_NLIMITS]; }; struct alt_name { char *name; struct alt_name *next; }; struct sd_hat { char *hat_name; unsigned int hat_magic; }; struct var_string { char *prefix; char *var; char *suffix; }; #define COD_READ_CHAR 'r' #define COD_WRITE_CHAR 'w' #define COD_APPEND_CHAR 'a' #define COD_EXEC_CHAR 'x' #define COD_LINK_CHAR 'l' #define COD_LOCK_CHAR 'k' #define COD_MMAP_CHAR 'm' #define COD_INHERIT_CHAR 'i' #define COD_UNCONFINED_CHAR 'U' #define COD_UNSAFE_UNCONFINED_CHAR 'u' #define COD_PROFILE_CHAR 'P' #define COD_UNSAFE_PROFILE_CHAR 'p' #define COD_LOCAL_CHAR 'C' #define COD_UNSAFE_LOCAL_CHAR 'c' #define OPTION_ADD 1 #define OPTION_REMOVE 2 #define OPTION_REPLACE 3 #define OPTION_STDOUT 4 #define OPTION_OFILE 5 #define BOOL int extern int preprocess_only; #define PATH_CHROOT_REL 0x1 #define PATH_NS_REL 0x2 #define PATH_CHROOT_NSATTACH 0x4 #define PATH_CHROOT_NO_ATTACH 0x8 #define PATH_MEDIATE_DELETED 0x10 #define PATH_DELEGATE_DELETED 0x20 #define PATH_ATTACH 0x40 #define PATH_NO_ATTACH 0x80 #ifdef DEBUG #define PDEBUG(fmt, args...) \ do { \ int pdebug_error = errno; \ fprintf(stderr, "parser: " fmt, ## args); \ errno = pdebug_error; \ } while (0) #else #define PDEBUG(fmt, args...) /* Do nothing */ #endif #define NPDEBUG(fmt, args...) /* Do nothing */ #define PERROR(fmt, args...) \ do { \ int perror_error = errno; \ fprintf(stderr, fmt, ## args); \ errno = perror_error; \ } while (0) #ifndef TRUE #define TRUE (1) #endif #ifndef FALSE #define FALSE (0) #endif #define MIN_PORT 0 #define MAX_PORT 65535 #ifndef unused #define unused __attribute__ ((unused)) #endif #define list_for_each(LIST, ENTRY) \ for ((ENTRY) = (LIST); (ENTRY); (ENTRY) = (ENTRY)->next) #define list_for_each_safe(LIST, ENTRY, TMP) \ for ((ENTRY) = (LIST), (TMP) = (LIST) ? (LIST)->next : NULL; (ENTRY); (ENTRY) = (TMP), (TMP) = (TMP) ? (TMP)->next : NULL) #define list_last_entry(LIST, ENTRY) \ for ((ENTRY) = (LIST); (ENTRY) && (ENTRY)->next; (ENTRY) = (ENTRY)->next) #define list_append(LISTA, LISTB) \ do { \ typeof(LISTA) ___tmp; \ list_last_entry((LISTA), ___tmp);\ ___tmp->next = (LISTB); \ } while (0) #define list_len(LIST) \ ({ \ int len = 0; \ typeof(LIST) tmp; \ list_for_each((LIST), tmp) \ len++; \ len; \ }) #define list_find_prev(LIST, ENTRY) \ ({ \ typeof(ENTRY) tmp, prev = NULL; \ list_for_each((LIST), tmp) { \ if (tmp == (ENTRY)) \ break; \ prev = tmp; \ } \ prev; \ }) #define list_remove_at(LIST, PREV, ENTRY) \ if (PREV) \ (PREV)->next = (ENTRY)->next; \ if ((ENTRY) == (LIST)) \ (LIST) = (ENTRY)->next; \ (ENTRY)->next = NULL; \ #define list_remove(LIST, ENTRY) \ do { \ typeof(ENTRY) prev = list_find_prev((LIST), (ENTRY)); \ list_remove_at((LIST), prev, (ENTRY)); \ } while (0) #define DUP_STRING(orig, new, field, fail_target) \ do { \ (new)->field = ((orig)->field) ? strdup((orig)->field) : NULL; \ if (((orig)->field) && !((new)->field)) \ goto fail_target; \ } while (0) #define u8 unsigned char #define u16 uint16_t #define u32 uint32_t #define u64 uint64_t #define cpu_to_le16(x) ((u16)(htole16 ((u16) x))) #define cpu_to_le32(x) ((u32)(htole32 ((u32) x))) #define cpu_to_le64(x) ((u64)(htole64 ((u64) x))) /* The encoding for kernal abi > 5 is * 28-31: reserved * 20-27: policy version * 12-19: policy abi version * 11: force complain flag * 10: reserved * 0-9: kernel abi version */ #define ENCODE_VERSION(C, P, PABI, KABI) \ ({ \ u32 version = (KABI) & 0x3ff; \ if ((KABI) > 5) { \ version |= (C) ? 1 << 11 : 0; \ version |= ((PABI) & 0xff) << 12; \ version |= ((P) & 0xff) << 20; \ } \ version; \ }) /* The parser fills this variable in automatically */ #define PROFILE_NAME_VARIABLE "profile_name" /* from parser_common.c */ extern uint32_t policy_version; extern uint32_t parser_abi_version; extern uint32_t kernel_abi_version; extern int force_complain; extern int perms_create; extern int net_af_max_override; extern int kernel_load; extern int kernel_supports_setload; extern int kernel_supports_network; extern int kernel_supports_policydb; extern int kernel_supports_diff_encode; extern int kernel_supports_mount; extern int kernel_supports_dbus; extern int kernel_supports_signal; extern int kernel_supports_ptrace; extern int kernel_supports_unix; extern int kernel_supports_stacking; extern int conf_verbose; extern int conf_quiet; extern int names_only; extern int option; extern int current_lineno; extern dfaflags_t dfaflags; extern const char *progname; extern char *profilename; extern char *profile_ns; extern char *current_filename; extern FILE *ofile; extern int read_implies_exec; extern void pwarn(const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2))); /* from parser_main (cannot be used in tst builds) */ extern int force_complain; extern void display_version(void); extern int show_cache; extern int skip_cache; extern int skip_read_cache; extern int write_cache; extern int cond_clear_cache; extern int force_clear_cache; extern int create_cache_dir; extern int preprocess_only; extern int skip_mode_force; extern int abort_on_error; extern int skip_bad_cache_rebuild; extern int mru_skip_cache; extern int debug_cache; /* provided by parser_lex.l (cannot be used in tst builds) */ extern FILE *yyin; extern void yyrestart(FILE *fp); extern int yyparse(void); extern void yyerror(const char *msg, ...); extern int yylex(void); /* parser_include.c */ extern const char *basedir; /* parser_regex.c */ #define default_match_pattern "[^\\000]*" #define anyone_match_pattern "[^\\000]+" #define glob_default 0 #define glob_null 1 extern pattern_t convert_aaregex_to_pcre(const char *aare, int anchor, int glob, std::string& pcre, int *first_re_pos); extern int build_list_val_expr(std::string& buffer, struct value_list *list); extern int convert_entry(std::string& buffer, char *entry); extern int clear_and_convert_entry(std::string& buffer, char *entry); extern int process_regex(Profile *prof); extern int post_process_entry(struct cod_entry *entry); extern int process_policydb(Profile *prof); extern int process_policy_ents(Profile *prof); /* parser_variable.c */ int expand_entry_variables(char **name); extern int process_variables(Profile *prof); extern struct var_string *split_out_var(const char *string); extern void free_var_string(struct var_string *var); /* parser_misc.c */ extern void warn_uppercase(void); extern int is_blacklisted(const char *name, const char *path); extern struct value_list *new_value_list(char *value); extern struct value_list *dup_value_list(struct value_list *list); extern void free_value_list(struct value_list *list); extern void print_value_list(struct value_list *list); extern struct cond_entry *new_cond_entry(char *name, int eq, struct value_list *list); extern void move_conditional_value(const char *rulename, char **dst_ptr, struct cond_entry *cond_ent); extern void free_cond_entry(struct cond_entry *ent); extern void free_cond_list(struct cond_entry *ents); extern void print_cond_entry(struct cond_entry *ent); extern char *processid(const char *string, int len); extern char *processquoted(const char *string, int len); extern char *processunquoted(const char *string, int len); extern int get_keyword_token(const char *keyword); extern int name_to_capability(const char *keyword); extern int get_rlimit(const char *name); extern char *process_var(const char *var); extern int parse_mode(const char *mode); extern int parse_X_mode(const char *X, int valid, const char *str_mode, int *mode, int fail); bool label_contains_ns(const char *label); bool parse_label(bool *_stack, char **_ns, char **_name, const char *label, bool yyerr); extern struct cod_entry *new_entry(char *id, int mode, char *link_id); /* returns -1 if value != true or false, otherwise 0 == false, 1 == true */ extern int str_to_boolean(const char* str); extern struct cod_entry *copy_cod_entry(struct cod_entry *cod); extern void free_cod_entries(struct cod_entry *list); extern void __debug_capabilities(uint64_t capset, const char *name); void debug_cod_entries(struct cod_entry *list); #define SECONDS_P_MS (1000LL * 1000LL) long long convert_time_units(long long value, long long base, const char *units); /* parser_symtab.c */ struct set_value { char *val; struct set_value *next; }; extern int add_boolean_var(const char *var, int boolean); extern int get_boolean_var(const char *var); extern int new_set_var(const char *var, const char *value); extern int add_set_value(const char *var, const char *value); extern struct set_value *get_set_var(const char *var); extern char *get_next_set_value(struct set_value **context); extern int delete_set_var(const char *var_name); extern void dump_symtab(void); extern void dump_expanded_symtab(void); void free_symtabs(void); /* parser_alias.c */ extern int new_alias(const char *from, const char *to); extern int replace_profile_aliases(Profile *prof); extern void free_aliases(void); /* parser_merge.c */ extern int profile_merge_rules(Profile *prof); /* parser_interface.c */ extern int load_profile(int option, aa_kernel_interface *kernel_interface, Profile *prof, int cache_fd); extern void sd_serialize_profile(std::ostringstream &buf, Profile *prof, int flatten); extern int sd_load_buffer(int option, char *buffer, int size); extern int cache_fd; /* parser_policy.c */ extern void add_to_list(Profile *profile); extern void add_hat_to_policy(Profile *policy, Profile *hat); extern int add_entry_to_x_table(Profile *prof, char *name); extern void add_entry_to_policy(Profile *policy, struct cod_entry *entry); extern void post_process_file_entries(Profile *prof); extern void post_process_rule_entries(Profile *prof); extern int post_process_policy(int debug_only); extern int process_profile_regex(Profile *prof); extern int process_profile_variables(Profile *prof); extern int process_profile_policydb(Profile *prof); extern int post_merge_rules(void); extern int merge_hat_rules(Profile *prof); extern Profile *merge_policy(Profile *a, Profile *b); extern int load_policy(int option, aa_kernel_interface *kernel_interface, int cache_fd); extern int load_hats(std::ostringstream &buf, Profile *prof); extern int load_flattened_hats(Profile *prof, int option, aa_kernel_interface *kernel_interface, int cache_fd); extern void dump_policy_hats(Profile *prof); extern void dump_policy_names(void); void dump_policy(void); void free_policies(void); #endif /** __AA_PARSER_H */ apparmor-2.13.3/parser/po/0000755000175000017500000000000013502024172013117 5ustar jjjjapparmor-2.13.3/parser/po/zh_CN.po0000644000175000017500000006073213502024172014470 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 04:12+0000\n" "Last-Translator: Novell Language \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: zh_CN\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "错误:内存不足。\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "错误:basedir %s 不是目录,正在跳过。\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "错误:无法将目录 %s 添加到搜索路径。\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "错误:无法分配内存。\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "写入位置无效\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "拒绝许可权限\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "内存不足\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "配置文件未遵守协议\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "配置文件和签名不匹配\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "配置文件版本不受 Apparmor 模块支持\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "配置文件已存在\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "配置文件不存在\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: 无法添加\"%s\"。 " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: 无法替换\"%s\"。 " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: 无法去除\"%s\"。 " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: 无法写入 stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: 声明:无效选项: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "添加\"%s\"成功。\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "替换\"%s\"成功。\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "去除\"%s\"成功。\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PANIC 无效的递增缓冲区:%p pos %p ext %p size %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "无法打开 %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "内存分配错误:无法去除 ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "内存分配错误:无法去除 %s:%s。" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "无法创建工作区域\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "无法序列化配置文件 %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: 无法写入整个配置文件项\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "发现意外字符: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) 发现意外字符:“%s”" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: 无法为子域基底装入点分配内存\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "警告:无法在 %s 中找到合适的 fs,是否已装入?\n" "使用 --subdomainfs 覆盖。\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s:对不起。您需要 root 特权才能运行此程序。\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s:警告!您已将此程序设置为 setuid root。\n" "任何可以运行此程序的人都可以更新 AppArmor 配置文件。\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "错误:无法读取配置文件 %s: %s。\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "内存分配错误。" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: 文件中发现错误。正在中止。\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "不允许使用大写限定符 “RWLIMX”,请转换为小写\n" "有关细节,请参见 apparmor.d(5) 手册页。\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "冲突的“a”和“w”许可权限互相排斥。" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "Exec 限定符'i'无效,已指定了和其冲突的限定符" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "无限制 exec 限定符 (%c%c) 允许将一些危险的环境变量传递到无限制的进程;有关细节,请参见“man 5 apparmor.d”。\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "Exec 限定符“%c”无效,已指定了与其冲突的限定符" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "执行限定符“%c%c”无效,与已经指定的限定符冲突" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "内部:输入中有意外方式字符“%c”" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "内部错误产生无效的权限 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "AppArmor 语法分析器错误:%s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "无法合并项。内存不足\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "无法创建别名 %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "配置文件标志“debug”不再有效。" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "无效的配置文件标志:%s。" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "声明:`rule'返回 NULL。" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "模式无效,在拒绝规则中,“x”不能在执行限定符“i”、“p”或“u”之后" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "模式无效,“x”必须在执行限定符“i”、“p”、“c”或“u”之后" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "方式无效,“x”前面必须带有 exec 限定符“i”、“p”或“u”" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "声明:“network_rule”返回无效协议。" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "声明:“change_profile”返回 NULL。" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "声明:'hat rule'返回 NULL。" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "声明:“local_profile rule”返回 NULL。" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "取消设置 if 表达式中使用的布尔变量 %s" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "不安全规则缺少 exec 许可权限" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "子集只能使用链接规则。" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "链接和执行权限冲突,由于一个文件规则使用 ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "在命名的配置文件转换中,链接权限不受允许。\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "是否缺少行结束字符?(项:%s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "无效网络项。" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "功能 %s 无效。" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: 不合法的左侧大括号 {,不允许嵌套分组\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "%s: Regex 分组错误:{} 内的项目数无效\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "%s: Regex 分组错误:无效的右侧花括号 },未检测到匹配的左侧花括号 {\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "%s: Regex 分组错误:组或字符类未关闭,需要右侧花括号 }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: 检测到内部缓冲区溢出,超过 %d 个字符\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: 无法对输入行'%s'进行语法分析\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "合并配置文件 %s 的规则时出错,无法装载\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "错误 配置文件 %s 包含不能与此内核一起使用的策略元素:\n" "\t不允许“*”、“?”、字符范围,也不允许“或”操作。\n" "\t“**”只能在规则结尾处使用。\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "处理配置文件 %s 的 regex 时出错,无法装载\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "扩展配置文件 %s 的变量时出错,无法装载\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "为配置文件 %s 添加 hat 访问规则时出错\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "配置文件 %s 中存在错误,未能装载\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s:在后处理中发现错误。正在中止。\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "%s:在 Regex 后处理中发现错误。正在中止。\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s:在后处理中发现错误。正在中止。\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "%s: 在组合规则后处理中发现错误。正在中止。\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/ug.po0000644000175000017500000005106413502024172014100 0ustar jjjj# Uyghur translation for apparmor # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 22:00+0000\n" "Last-Translator: AppArmor list \n" "Language-Team: Uyghur \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: ug\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/nb.po0000644000175000017500000006152113502024172014063 0ustar jjjj# translation of apparmor-parser.po to norsk bokmål # translation of apparmor-parser.po to # translation of subdomain-parser.po to # This file is distributed under the same license as the PACKAGE package. # Copyright (C) YEAR Immunix, Inc. # # Olav Pettershagen , 2005, 2007. # Rune Nordbøe Skillingstad , 2007. # Olav P. , 2008. # Olav Pettershagen , 2008. msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 03:17+0000\n" "Last-Translator: Olav Pettershagen \n" "Language-Team: norsk bokmål\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: nb\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Feil: For lite minne.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Feil: basedir %s er ikke en katalog, hopper over.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Feil: Kan ikke legge katalogen %s til søkesti\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Feil: Kunne ikke tilordne minne\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Ugyldig lagringsposisjon\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Manglende rettigheter\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "For lite minne\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profilen samsvarer ikke med protokollen\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profilen samsvarer ikke med signaturen\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Profilversjonen støttes ikke av Apparmor-modulen\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profilen finnes allerede\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profilen finnes ikke\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Kan ikke legge til \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Kan ikke erstatte \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Kan ikke slette \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Kan ikke skrive til stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: Ugyldig valg: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Lagt til for \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Erstattet for \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Slettet for \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PANIC ugyldig inkrementbuffer %p pos %p ext %p size %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Kan ikke åpne %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Minnetilordningsfeil: Kan ikke fjerne ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Minnetilordningsfeil: Kan ikke fjerne %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "Kan ikke opprette arbeidsområde\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "kan ikke serietilordne profilen %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Kan ikke lagre hele profiloppføringen\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Fant uventet tegn: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(nettwork_mode) Fant uventet tegn: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: Kunne ikke tilordne minne for subdomenebasens monteringspunkt\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Advarsel: Kunne ikke finne en egnet fs i %s, er den montert?\n" "Bruk --subdomainfs for å overstyre.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Beklager. Dette programmet må kjøres som rot.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Advarsel! Du har definert 'setuid root' for dette programmet.\n" "Alle som kan kjøre dette programmet, kan oppdatere dine AppArmor-profiler.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Feil: Kunne ikke lese profil %s:%s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Minnetilordningsfeil." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Feil funnet i filen. Avbryter.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Valg med store bokstaver \"RWLIMX\" brukes ikke lenger. Konverter til små " "bokstaver.\n" "Se manualsiden apparmor.d(5).\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Conflikt 'a'- and 'w'-tillatelser kan ikke brukes samtidig." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Exec-valget 'i' er ugyldig. Et annen valg som er i konflikt med dette, er " "allerede spesifisert" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "Et ubegrenset exec-argument (%c%c) kan medføre at farlige miljøvariabler " "sendes til den ubegrensede prosessen. Se 'man 5 apparmor.d'.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "Exec-valget '%c' er ugyldig. Et annen valg er allerede spesifisert" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "Kjørevalget '%c%c' er ugyldig. Et annet valg er allerede spesifisert" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Intern feil: Uventet modustegn '%c' angitt" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Intern feil genererte ugyldig rettighet 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "Feil under AppArmor-analyse: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Kan ikke samordne oppføringer. For lite minne\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Kunne ikke opprette aliaset %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "valget er ikke lenger gyldig" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Ugyldig profilvalg: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Assert: 'rule' returnerte NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Ugyldig modus, i avvisingsregler må ikke kjørevalgene eller " "komme foran 'x'." #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "Ugyldig modus, 'x' må komme etter kjørevalgt 'i', 'p' eller 'u'" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "Ugyldig modus. 'x' må komme etter exec-valget 'i', 'p' eller 'u'" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Assert: 'network_rule' returnerte NULL." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Assert: 'change_profile' returnerte NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Assert: 'hat rule' returnerte NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Assert: 'local_profile' returnerte NULL." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Udefinert boolsk variabel %s brukt i if-uttrykk" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "usikker regel uten exec-tillatelser" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "kan bare brukes med lenkeregler" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "Lenke- og kjørerettigheter er i konflikt med en regelfil som bruker" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "Lenkerettigheter er ikke tillatt for en navngitt profiloverføring.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "tegn for linjelslutt mangler? (oppføring: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Ugyldig nettverksoppføring." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Ugyldig egenskap %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: Åpen { ikke tillatt, nesting-gruppering ikke tillatt\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: Regex-grupperingsfeil: Ugyldig antall oppføringer mellom { og }\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Regex-grupperingsfeil: Ugyldig avsluttende }, ingen initial { funnet\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Regex-grupperingsfeil: Åpen grupperings- eller tegnklasse, lukket " "forventet }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Intern bufferlekkasje registrert, %d tegn overskredet\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Kan ikke analysere kommandolinje '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "FEIL under aktivering av regler for profil %s, kunne ikke laste\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "FEIL Profilen %s inneholder strategielementer som ikke kan brukes med denne " "kjernen:\n" "\t'*', '?', og alternerende elementer er ikke tillatt.\n" "\t'**' kan bare brukes på slutten av en regel.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "FEIL under behandling av regexs for profil %s, kunne ikke laste\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "FEIL under utvidelse av variabler for profil %s, kunne ikke laste\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "FEIL ved oppretting av hat-tilgangsregel for profilen %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "FEIL i profil %s, kunne ikke laste\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: Feil funnet under etterbehandling. Avbryter.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "%s: Feil funnet under etterbehandling av regex. Avbryter.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: Feil funnet under etterbehandling. Avbryter.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Feil funnet under etterbehandling av kombinasjonsregler. Avbryter.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/sl.po0000644000175000017500000005074113502024172014104 0ustar jjjj# translation of sl_SI.po to Slovenščina # translation of sl_SI.po to Slovenš?ina # Janez Krek , 2005. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 22:00+0000\n" "Last-Translator: Janez Krek \n" "Language-Team: Slovenščina \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: sl\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/oc.po0000644000175000017500000005225313502024172014067 0ustar jjjj# Occitan (post 1500) translation for apparmor # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2016-03-10 21:29+0000\n" "Last-Translator: Cédric VALMARY (Tot en òc) \n" "Language-Team: Occitan (post 1500) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: oc\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Error : memòria insufisenta.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Marrida posicion d'escritura\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Autorizacion refusada\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Pas pro de memòria\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Perfil inexistent\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s : impossible d'apondre « %s ». " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s : impossible de remplaçar « %s ». " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s : impossible de suprimir « %s ». " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Apondon capitat per « %s ».\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Supression capitada per « %s ».\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Impossible de dobrir %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "impossible de crear una zòna de trabalh\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "impossible de serializar lo perfil %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s : impossible d'escriure l'entrada de perfil completa\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "Impossible de dobrir « %s »" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Assert : « rule » a tornat NULL" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Assert : « hat rule » a tornat NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/vi.po0000644000175000017500000005114613502024172014104 0ustar jjjj# Vietnamese translation for YaST2 (@memory@). # Copyright © 2006 SUSE Linux Products GmbH. # Copyright © 2005, 2006 Gnome i18n Project for Vietnamese. # Phan Vĩnh Thịnh , 2006. # Clytie Siddall , 2005, 2006. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 22:32+0000\n" "Last-Translator: Phan Vĩnh Thịnh \n" "Language-Team: Vietnamese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: vi\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/ru.po0000644000175000017500000007601613502024172014117 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2016-03-29 14:53+0000\n" "Last-Translator: Eugene Roskin \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: ru\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Ошибка: Недостаточно памяти.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Ошибка: базовый каталог %s не является каталогом, пропускается.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Ошибка: не удалось добавить каталог %s в путь поиска.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Ошибка: не удалось выделить память\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Неверное положение записи\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Доступ запрещен\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Недостаточно памяти\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "Невозможно скопировать профиль: Недопустимый адрес памяти\n" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Профиль не соответствует протоколу\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Профиль не соответствует подписи\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Версия профиля не поддерживается модулем Apparmor\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Профиль уже существует\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Профиль не существует\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "Нет доступа; попытаться загрузить профиль с учётом ограничений?\n" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "Неизвестная ошибка (%d): %s\n" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Невозможно добавить \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Невозможно заменить \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Невозможно удалить \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Невозможно записать в stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "%s: Невозможно записать вывод в файл\n" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ПРЕДУПРЕЖДЕНИЕ: Недопустимый параметр: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Дополнение успешно выполнено для \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Замена для \"%s\" выполнена.\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Удаление для \"%s\" выполнено.\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "ТРЕВОГА! неправильный инкрементный буфер %p pos %p ext %p size %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "Сетевые правила, указанные в профиле %s не применяются\n" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "Недопустимый тип шаблона\n" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Невозможно открыть %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Ошибка выделения памяти: невозможно удалить ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Ошибка выделения памяти: невозможно удалить %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "невозможно создать рабочую область\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "невозможно сеарилизировать профиль %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Невозможно записать запись профиля целиком\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "%s: Невозможно записать во временные файлы все записи профиля\n" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "Невозможно открыть '%s'" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "fstat не выполнен для '%s'" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "opendir не выполнен для '%s'" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "stat не выполнен для '%s'" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "Невозможно открыть '%s' в '%s'" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Найден непредвиденный знак: \"%s\"" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "В определении переменных недопустимы завершающие точки" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) Найден непредвиденный знак: \"%s\"" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "Предупреждение от %s (%s%sстрока %d): %s" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: невозможно выделить память для точки монтирования базового поддомена\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Предупреждение: не удалось найти подходящий fs в %s; смонтирован?\n" "Чтобы переопределить, используйте поддомены.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Извините. Для запуска этой программы необходимы права администратора.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Предупреждение! Для этой программы задан идентификатор пользователя " "root.\n" "Любой пользователь, запустивший эту программу, сможет обновить ваши профили " "AppArmor.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Ошибка: не удалось прочитать профиль %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Ошибка выделения памяти." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Обнаружены ошибки в файле. Прерываем.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Ключи в верхнем регистре \"RWLIMX\" исключены; выполните преобразование к " "нижнему регистру\n" "Подробнее см. на стр. руководства apparmor.d(5).\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Конфликт взаимоисключающих разрешений \"a\" и \"w\"." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "Недопустимый ключ запуска \"i\", уже задан конфликтующий ключ" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "Ключ неограниченного выполнения (%c%c) разрешает передавать опасные " "переменные среды в неограниченный процесс. Подробнее см. \"man 5 " "apparmor.d\".\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "Недопустимый ключ запуска \"%c\", уже задан конфликтующий ключ" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Недопустимый спецификатор запуска '%c%c', уже определён конфликтующий " "спецификатор" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Внутренняя ошибка: непредвиденный знак \"%c\" при вводе" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Неверное разрешение 0x%llx вызвало внутреннюю ошибку\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "Ошибка анализатора AppArmor: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Невозможно объединить записи. Не хватает памяти\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "Вложение профиля должно начинаться с '/'." #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" "Имена профилей должны начинаться с a '/', пространства имён или ключевого " "слова 'profile' или 'hat'." #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Не удалось создать псевдоним %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "Флаг профиля chroot_relative конфликтует с namespace_relative" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "Флаг профиля mediate_deleted конфликтует с delegate_deleted" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" "Флаг профиля attach_disconnected конфликтует с no_attach_disconnected" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "Флаг профиля chroot_attach conflicts с chroot_no_attach" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "Флаг профиля 'debug' больше не используется." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Недопустимый флаг профиля: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Предупреждение: \"rule\" возвращает NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Недопустимый режим, в правилах запрещения перед 'x' не должен стоять ключ " "запуска 'i', 'p' или 'u'" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Недопустимый режим, перед 'x' должен стоять ключ запуска 'i', 'p', 'c' или " "'u'" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Недопустимый режим, перед \"x\" должен находиться ключ выполнения \"i\", " "\"p\" или \"u\"" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Предупреждение: \"network_rule\" возвращает недопустимый протокол." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Предупреждение: \"change_profile\" возвращает NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Предупреждение: \"hat rule\" возвращает NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Предупреждение: 'local_profile rule' возвратило NULL." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "В выражении IF используется незаданная логическая переменная %s" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "в правиле небезопасных отсутствуют разрешения на выполнения" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "подмножество может использоваться только с правилами связи." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" "разрешения на выполнение и связь конфликтуют с правилом файла, использующим -" ">" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" "разрешения на связь не допускаются при перемещении именованного профиля.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "отсутствует знак конца строки? (запись: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Недопустимая сетевая запись." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Недопустимая возможность %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "Ошибка анализатора AppArmor,%s%s в строке %d: %s\n" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: Неверное открытие {, вложенная группировки не допускаются\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "%s: Ошибка группировки Regex: Неверное число объектов между {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Ошибка группировки Regex: Неверное закрытие }, обнаружено что нет " "соответствующего открытия {\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: ошибка группировки Regex. Не закрыта группировка или класс знаков; " "ожидается закрывающая скобка }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Обнаружено переполнение внутреннего буфера, лишние %d знаков\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: невозможно обработать строку ввода \"%s\"\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" "%s: Недопустимое имя профиля '%s' - неправильное регулярное выражение\n" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "ОШИБКА при объединении правил для профиля %s, не удалось загрузить\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "ОШИБКА: профиль %s содержит элементы политики, неподходящие для этого ядра:\n" "\t\"*\", \"?\", диапазоны знаков и чередования не допускаются.\n" "\t\"**\" может использоваться только в конце правила.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" "ОШИБКА при обработке регулярных выражений для профиля %s; не удалось " "загрузить\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" "Ошибка при развертывании переменных для профиля %s; не удалось загрузить\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "ОШИБКА при добавлении правила доступа к HAT для профиля %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "ОШИБКА в профиле %s, не удалось загрузить\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: Обнаружены ошибки во время постобработки. Прекращение работы.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" "%s: обнаружены ошибки при заключительной обработке регулярного выражения. " "Операция прерывается.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: Обнаружены ошибки во время постобработки. Прекращение работы.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: обнаружены ошибки при заключительной обработке объединения правил. " "Операция прерывается.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "Невозможно выполнить включение каталога '%s' в '%s'" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "Недостаточно памяти" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "Невозможно создать временный каталог: %s\n" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "Расположение файла во временном каталоге: %s\n" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "Невозможно обновить временный каталог: %s\n" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "префикс владельца не разрешён" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "%s: Невозможно записать %s\n" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" "Ошибка: невозможно прочитать двоичный профиль или временный файл %s: %s.\n" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "Ошибка: невозможно прочитать временный файл '%s', пропуск...\n" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/sr.po0000644000175000017500000005075213502024172014114 0ustar jjjj# Serbian translations for boot loader # Copyright (C) 2005 SUSE Linux GmbH # Copyright © 2005 Danilo Segan # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 22:31+0000\n" "Last-Translator: Данило Шеган \n" "Language-Team: Serbian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: sr\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/lo.po0000644000175000017500000005063313502024172014100 0ustar jjjj# Lao message file for YaST2 (@memory@). # Copyright (C) 2006 SUSE Linux Products GmbH. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 22:25+0000\n" "Last-Translator: i18n@suse.de\n" "Language-Team: Lao \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: lo\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/fr.po0000644000175000017500000006615713502024172014105 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2016-04-28 10:19+0000\n" "Last-Translator: Sylvie Gallet \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: fr\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Erreur : mémoire saturée.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Erreur : basedir %s n'est pas un répertoire, ignoré.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" "Erreur : impossible d'ajouter le répertoire %s au chemin de recherche.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Erreur : impossible d'allouer de la mémoire\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Mauvaise position d'écriture\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Permission refusée\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Mémoire saturée\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "Impossible de copier le profil : adresse mémoire incorrecte\n" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profil non conforme au protocole\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Le profil ne correspond pas à la signature\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Version de profil non prise en charge par le module Apparmor\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profil déjà existant\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profil inexistant\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "Erreur inconnue (%d) : %s\n" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s : impossible d'ajouter « %s ». " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s : impossible de remplacer « %s ». " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s : impossible de supprimer « %s ». " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s : impossible d'écrire vers la sortie standard (stdout)\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "%s : impossible d'écrire vers le fichier de sortie\n" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s : ASSERT : option incorrecte : %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Ajout réussi pour « %s ».\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Remplacement réussi pour « %s ».\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Suppression réussie pour « %s ».\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "ALARME tampon d'incrément incorrect %p pos %p ext %p taille %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "Type de motif inconnu\n" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Impossible d'ouvrir %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Erreur d'allocation mémoire : impossible de supprimer ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Erreur d'allocation mémoire : impossible de supprimer %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "impossible de créer une zone de travail\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "impossible de sérialiser le profil %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s : impossible d'écrire l'entrée de profil complète\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "%s : impossible d'écrire l'entrée de profil complète dans le cache\n" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "Impossible d'ouvrir « %s »" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "Échec de fstat pour « %s »" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "Impossible d'ouvrir « %s » dans « %s »" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Caractère inattendu trouvé : « %s »" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "Les déclarations de variables n'acceptent pas les virgules finales" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) Caractère inattendu trouvé : '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "Avertissement de %s (%s%sligne %d) : %s" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s : impossible d'allouer de la mémoire pour point de montage de base de " "sous-domaine\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Avertissement : impossible de trouver un système de fichiers approprié dans " "%s, est-il monté ?\n" "Utilisez --subdomainfs pour remplacer.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s : désolé. Les privilèges root sont nécessaires pour exécuter ce " "programme.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s : avertissement ! Vous avez défini le setuid de ce programme comme root.\n" "Toute personne capable d'exécuter ce programme peut mettre à jour vos " "profils AppArmor.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Erreur : impossible de lire le profil %s : %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Erreur d'allocation mémoire." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s : erreurs trouvées dans un fichier. Annulation.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Les qualificatifs en majuscules « RWLIMX » sont déconseillés. Remplacez-les " "par des minuscules\n" "Reportez-vous à la page de manuel apparmor.d(5) pour plus de détails.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Les autorisations « a » et « w » en conflit s'excluent mutuellement." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Qualificatif d'exécution « i » incorrect, en conflit avec un qualificatif " "déjà défini" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "Le qualificatif d'exécution non confiné (%c%c) permet à certaines variables " "d'environnement dangereuses d'être transmises vers le processus non " "confiné ; « man 5 apparmor.d » pour plus de détails.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Qualificatif d'exécution « %c » non valide, qualificatif déjà indiqué" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Qualificatif d'exécution « %c%c » incorrect, en conflit avec un qualificatif " "déjà défini" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Interne« : caractère de mode « %c » inattendu en entrée" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Erreur interne générée par une autorisation invalide 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "Erreur de l'analyseur AppArmor : %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Impossible de fusionner les entrées. Mémoire saturée\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "L'ajout à un profil doit commencer par un « / »" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" "Les noms de profils doivent commencer par un « / », un espace de noms ou un " "des mots-clés « profile » ou « hat »." #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Impossible de créer l'alias %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" "Le drapeau de profil chroot_relative est en conflit avec namespace_relative" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" "Le drapeau de profil mediate_deleted est en conflit avec delegate_deleted" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" "Le drapeau de profil attach_disconnected est en conflit avec " "no_attach_disconnected" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" "Le drapeau de profil chroot_attach est en conflit avec chroot_no_attach" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "Le drapeau de profil « debug » n'est plus valide." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Drapeau de profil non valide : %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Assert : « rule » a retourné NULL" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Mode incorrect : dans les règles de refus, « x » ne doit pas être précédé du " "qualificatif d'exécution « i », « p » ou « u »." #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Mode incorrect : « x » doit être précédé du qualificatif d'exécution « i », " "« p », « c » ou « u »." #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Mode incorrect : « x » doit être précédé du qualificatif d'exécution « i », " "« p » ou « u »." #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Assert : « network_rule » retourne un protocole non valide." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Assert : « change_profile » a retourné NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Assert : « hat rule » a retourné NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Assert : « local_profile rule » a retourné NULL." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Annuler la variable booléenne %s utilisée dans l'expression if" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "autorisations d'exécution manquant de règle, non sûres" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "le sous-ensemble ne peut être utilisé qu'avec des règles de liaison." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" "les autorisations de liaison et d'exécution sont en conflit avec une règle " "de fichier qui utilise ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" "les autorisations de liaison ne sont pas autorisées sur une transition de " "profil nommée.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "caractère de fin de ligne manquant ? (entrée : %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Entrée réseau non valide." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Capacité %s invalide." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "Erreur de l'analyseur AppArmor pour %s%s%s à la ligne %d : %s\n" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "Erreur de l'analyseur AppArmor, %s%s ligne %d : %s\n" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s : { ouvrante incorrecte, regroupements imbriqués non autorisés\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s : erreur de regroupement Regex : nombre incorrect d'éléments entre {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s : erreur de regroupement Regex : } fermante incorrecte, aucune { ouvrante " "détectée\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s : erreur de regroupement Regex : regroupement ou classe de caractères non " "fermé, fermante attendue }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" "%s : dépassement de tampon interne détecté, %d caractères en dépassement\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s : impossible d'analyser la ligne en entrée « %s »\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" "%s : Nom de profil non valide « %s » - expression régulière incorrecte\n" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" "ERREUR de fusion des règles pour le profil %s, le chargement a échoué\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "ERREUR le profil %s contient des éléments de stratégie non utilisables avec " "ce noyau :\n" "\t« * », « ? », les plages de caractères et les permutations ne sont pas " "autorisées.\n" "\t« ** » peut uniquement être utilisé à la fin d'une règle.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" "ERREUR lors du traitement Regex du profil %s, le chargement a échoué\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" "ERREUR lors de l'extension de variables pour le profil %s, le chargement a " "échoué\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" "Une ERREUR s'est produite lors de l'ajout de la règle d'accès hat pour le " "profil %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "ERREUR dans le profil %s, échec du chargement\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s : erreurs trouvées lors du post-traitement. Abandon.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "%s : erreurs trouvées lors du post-traitement Regex. Annulation.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s : erreurs trouvées lors du post-traitement. Abandon.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s : erreurs trouvées lors de la combinaison des règles de post-traitement. " "Annulation.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "Mémoire saturée" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/ka.po0000644000175000017500000005102113502024172014051 0ustar jjjj# @TITLE@ # Copyright (C) 2006, SUSE Linux GmbH, Nuremberg # FIRST AUTHOR , YEAR. # # This file is distributed under the same license as @PACKAGE@ package. FIRST # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 22:25+0000\n" "Last-Translator: George Machitidze \n" "Language-Team: Georgian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: ka\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/wa.po0000644000175000017500000005102413502024172014070 0ustar jjjj# Translation into the walloon language. # Copyright (C) 2007 SUSE Linux Products GmbH. # Pablo Saratxaga , 2001, 2004. # Jean Cayron , 2007. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 22:32+0000\n" "Last-Translator: Jean Cayron \n" "Language-Team: Walloon \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: wa\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/he.po0000644000175000017500000005071613502024172014064 0ustar jjjj# Hebrew message file for YaST2 (@memory@). # Copyright (C) 2005 SUSE Linux Products GmbH. # Copyright (C) 2004 SuSE Linux AG. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 22:22+0000\n" "Last-Translator: xxx \n" "Language-Team: Hebrew \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: he\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/zh_TW.po0000644000175000017500000006066413502024172014526 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 02:42+0000\n" "Last-Translator: Novell Language \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: zh_TW\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "錯誤:記憶體不足。\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "錯誤︰基本目錄 %s 不是目錄,正在跳過。\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "錯誤︰無法將目錄 %s 新增至搜尋路徑。\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "錯誤:無法配置記憶體。\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "不良的寫入位置\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "許可權被拒絕\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "記憶體不足\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "設定檔不符合通訊協定\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "設定檔不符合簽名\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Apparmor 模組不支援該設定檔版本\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "設定檔已存在\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "設定檔不存在\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: 無法新增 \"%s\"。 " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: 無法取代 \"%s\"。 " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: 無法移除 \"%s\"。 " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: 無法寫入至 stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: 顯示:無效的選項: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "\"%s\" 附加成功。\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "\"%s\" 取代成功。\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "\"%s\" 移除成功。\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PANIC 不良的增量緩衝區 %p pos %p ext %p size %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "無法開啟 %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "記憶體配置錯誤:無法移除 ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "記憶體配置錯誤:無法移除 %s:%s。" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "無法建立工作區\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "無法序列化設定檔 %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: 無法寫入整個設定檔項目\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "找到非預期的字元: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(網路模式) 發現非預期的字元︰%s" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: 無法為子網域基地裝載點配置記憶體\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "警告︰%s 中找不到適合的 fs,是否已裝載?\n" "請使用 --subdomainfs 覆寫。\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s︰抱歉。您必須具有根使用者權限才能執行此程式。\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s︰警告!您已將此程式設定為 setuid root。\n" "任何可執行此程式的使用者均可更新您的 AppArmor 設定檔。\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "錯誤︰無法讀取設定檔 %s︰%s。\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "記憶體配置錯誤。" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: 檔案中發現錯誤。正在中止。\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "大寫修飾詞「RWLIMX」已廢棄,請將其轉換成小寫\n" "如需詳細資料,請參閱 apparmor.d(5) manpage。\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "衝突的「a」與「w」許可互不相容。" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "Exec 修飾語「i」是無效的,已指定衝突的修飾語" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "未設限 exec 修飾詞 (%c%c) 允許將某些危險環境變數傳遞至未設限程序;如需詳細資料,請參閱 man 5 apparmor.d。\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "Exec 修飾詞「%c」無效,指定了衝突的修飾詞" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "Exec 修飾詞「%c%c」無效,指定了衝突的修飾詞" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "內部:輸入中存在非預期的模式字元「%c」" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "內部錯誤產生無效許可權 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "AppArmor 剖析程式錯誤︰%s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "無法合併項目。記憶體不足\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "無法建立別名 %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "設定檔旗標「debug」不再有效。" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "設定檔旗標 %s 無效。" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "顯示:`rule' 傳回 NULL。" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "無效模式,拒絕規則「x」的前面必須是 Exec 修飾詞「i」、「p」或「u」" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "無效模式,「x」的前面必須是 Exec 修飾詞「i」、「p」、「c」或「u」" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "無效模式,「x」的前面必須是 Exec 修飾詞「i」、「p」或「u」" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "提示︰「network_rule」傳回無效的通訊協定。" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "提示︰「change_profile」傳回 NULL。" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "顯示:'hat rule' 傳回 NULL。" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "顯示:「local_profile rule」傳回 NULL。" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "取消設定 if 運算式中使用的布林變數 %s" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "不安全規則缺少 exec 許可權" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "子集只能與連結規則一起使用。" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "使用 -> 的檔案規則有連結許可權與執行許可權衝突" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "不允許對指定的設定檔轉換使用連結許可權。\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "找不到行尾字元?(項目: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "網路項目無效。" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "功能 %s 無效。" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: 非法開啟 {, 不允許巢狀群組\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "%s: Regex 群組錯誤:無效的項目數在 {} 之間\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "%s: Regex 群組錯誤:非法關閉 }, 無相符的開啟 { 已偵測到\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "%s︰Regex 群組錯誤:存在未關閉的群組或字元類別,需要關閉}\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: 偵測到內部緩衝區溢位,超過 %d 個字元\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: 無法剖析輸入行 '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "為設定檔 %s 合併規則時發生錯誤,無法載入\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "錯誤 設定檔 %s 包含此核心無法使用的規則元素︰\n" "\t不允許使用「*」、「?」、字元範圍和替代項。\n" "\t「**」僅可用於規則的末尾。\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "為設定檔 %s 處理 regexs 時發生錯誤,無法載入\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "展開設定檔 %s 的變數時發生錯誤,無法載入\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "新增對設定檔 %s 的 hat 存取規則時出錯\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "設定檔 %s 中有錯誤,載入失敗\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s:後處理期間發現錯誤。正在中止。\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "%s︰regex 後處理期間發現錯誤。正在中止。\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s:後處理期間發現錯誤。正在中止。\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "%s: 結合規則後處理時發現錯誤。正在中止。\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/et.po0000644000175000017500000005274713502024172014106 0ustar jjjj# translation of apparmor-parser.et.po to Estonian # translation of # Copyright (C) 2006 SUSE Linux Products GmbH. # Estonian message file for YaST2 (@memory@). # # Ain Vagula , 2006. msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 01:50+0000\n" "Last-Translator: Ain Vagula \n" "Language-Team: Estonian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: et\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Viga: mälu ei jätku.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Viga: basedir %s pole kataloog, jäetakse vahele.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Viga: kataloogi %s pole võimalik otsinguteele lisada.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Viga: pole võimalik eraldada mälu.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Juurdepääs keelatud\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Mälu ei jätku\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profiil ei vasta protokollile\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profiil ei vasta signatuurile\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Profiili versioon ei ole Apparmori mooduli poolt toetatud\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profiil on juba olemas\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profiili pole olemas\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: \"%s\" ei saa lisada. " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: \"%s\" ei saa asendada. " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: \"%s\" ei saa eemaldada. " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: ei saa kirjutada standardväljundisse\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "\"%s\" asendamine õnnestus.\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "\"%s\" eemaldamine õnnestus.\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "%s - %s ei saa avada\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: kogu profiili kirjet ei saa kirjutada\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Leiti ootamatu märk: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Vabandust. Selle rakenduse käivitamiseks on vaja administraatori " "õigusi.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Viga: pole võimalik lugeda profiili %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Viga mälu eraldamisel." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: failis leiti vigu. Katkestamine.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "AppArmori parsimise viga: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Kirjeid ei suudetud ühendada. Mälu ei jätku\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "puudub realõpu märk? (kirje: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/pa.po0000644000175000017500000006047213502024172014070 0ustar jjjj# translation of apparmor-parser.pa.po to Panjabi # # A S Alam , 2007. # ASB , 2007. msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 03:31+0000\n" "Last-Translator: A S Alam \n" "Language-Team: Panjabi \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: pa\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "ਗਲਤੀ: ਮੈਮੋਰੀ ਖਤਮ ਹੋਈ।\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "ਗਲਤੀ: basedir %s ਇੱਕ ਡਾਇਰੈਕਟਰੀ ਨਹੀਂ ਹੈ, ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "ਗਲਤੀ: ਡਾਇਰੈਕਟਰੀ %s ਖੋਜ ਮਾਰਗ 'ਚ ਸ਼ਾਮਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ।\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "ਗਲਤੀ: ਮੈਮੋਰੀ ਜਾਰੀ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ।\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "ਗਲਤ ਲਿਖਣ ਸਥਿਤੀ\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "ਅਧਿਕਾਰ ਪਾਬੰਦੀ\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "ਮੈਮੋਰੀ ਤੋਂ ਬਾਹਰ\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "ਪਰੋਫਾਇਲ ਦਸਤਖਤ ਨਹੀਂ ਮਿਲਦੇ\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "ਪਰੋਫਾਇਲ ਵਰਜਨ ਅੱਪਾਰਮੋਰ ਮੋਡੀਊਲ ਵਲੋਂ ਸਹਾਇਕ ਨਹੀਂ ਹੈ\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "ਪਰੋਫਾਇਲ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "ਪਰੋਫਾਇਲ ਮੌਜੂਦ ਨਹੀਂ\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: \"%s\" ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਅਸਮਰੱਥ। " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: \"%s\" ਬਦਲਣ ਲਈ ਅਸਮਰੱਥ। " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: \"%s\" ਹਟਾਉਣ ਲਈ ਅਸਮਰੱਥ। " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: stdout ਉੱਤੇ ਲਿਖਣ ਲਈ ਅਸਮਰੱਥ\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: ਗਲਤ ਚੋਣ: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "ਸਫ਼ਲ \"%s\" ਲਈ ਹਟਾਉਣਾ\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "%s - %s ਖੋਲ੍ਹਣ ਲਈ ਅਸਫ਼ਲ\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "ਕੰਮ ਖੇਤਰ ਬਣਾਉਣ ਲਈ ਅਸਮਰੱਥ\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "ਪਰੋਫਾਇਲ %s ਸੀਰੀਅਲਾਈਜ਼ ਲਈ ਅਸਮਰੱਥ\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: ਪੂਰੀ ਪਰੋਫਾਇਲ ਐਂਟਰੀ ਲਿਖਣ ਲਈ ਅਸਮਰੱਥ\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "ਅਚਾਨਕ ਅੱਖਰ ਮਿਲਿਆ: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) ਅਣਜਾਣ ਅੱਖਰ ਮਿਲਿਆ: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: ਅਫਸੋਸ ਤੁਹਾਨੂੰ ਇਹ ਪਰੋਗਰਾਮ ਚਲਾਉਣ ਲਈ ਰੂਟ ਅਧਿਕਾਰ ਚਾਹੀਦੇ ਹਨ।\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: ਚੇਤਾਵਨੀ! ਤੁਸੀਂ ਇਹ ਪਰੋਗਰਾਮ ਲਈ setuid root ਸੈੱਟ ਕੀਤਾ ਹੈ।\n" "ਕੋਈ ਵੀ, ਜੋ ਕਿ ਇਹ ਪਰੋਗਰਾਮ ਚਲਾ ਸਕਦਾ ਹੈ, ਉਹ ਤੁਹਾਡਾ ਅੱਪਆਰਮੋਰ ਪਰੋਫਾਇਲ ਅੱਪਡੇਟ ਕਰ " "ਸਕਦਾ ਹੈ।\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "ਗਲਤੀ: ਪਰੋਫਾਇਲ %s ਪੜ੍ਹਿਆ ਨਹੀਂ ਜਾ ਸਕਿਆ: %s\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "ਮੈਮੋਰੀ ਜਾਰੀ ਕਰਨ ਗਲਤੀ।" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: ਫਾਇਲ 'ਚ ਗਲਤੀਆਂ ਮਿਲੀਆਂ। ਵਿੱਚੇ ਛੱਡਿਆ ਜਾਂਦਾ ਹੈ।\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "AppArmor ਪਾਰਸ ਗਲਤੀ: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "ਐਂਟਰੀਆਂ ਮਰਜ਼ ਨਹੀਂ ਕੀਤੀਆਂ ਜਾ ਸਕੀਆਂ। ਮੈਮੋਰੀ ਖਤਮ ਹੋਈ।\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "ਕੀ ਲਾਈਨ ਅੱਖਰ ਦਾ ਖਾਤਮਾ ਨਹੀਂ ਹੈ? (ਐਂਟਰੀ: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "ਗਲਤ ਨੈੱਟਵਰਕ ਐਂਟਰੀ ਹੈ।" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Regex ਗਰੁੱਪਿੰਗ ਗਲਤੀ। ਨਾ-ਬੰਦ ਹੋਈ ਗਰੁੱਪਿੰਗ ਜਾਂ ਅੱਖਰ ਕਲਾਸ, ਬੰਦ } ਦੀ ਲੋੜ ਸੀ\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: ਅੰਦਰੂਨੀ ਬਫ਼ਰ ਓਵਰਫਲੋ ਮਿਲਿਆ, %d ਅੱਖਰ ਵੱਧ ਗਏ ਹਨ\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: ਇੰਪੁੱਟ ਲਾਈਨ '%s' ਪਾਰਸ ਕਰਨ ਲਈ ਅਸਮਰੱਥ\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "ਪਰੋਫਾਇਲ %s ਲਈ ਰੂਲ ਮਿਲਾਨ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ, ਲੋਡ ਕਰਨ ਲਈ ਫੇਲ੍ਹ\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "ਪਰੋਫਾਇਲ %s regexs ਪਰੋਸੈਸ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ, ਲੋਡ ਕਰਨ ਲਈ ਫੇਲ੍ਹ\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "ਪਰੋਫਾਇਲ %s ਲਈ ਵੇਰੀਬਲ ਐਕਸਪੈਂਡ ਕਰਨ ਦੌਰਾਨ ਗਲਤੀ, ਲੋਡ ਕਰਨ ਲਈ ਫੇਲ੍ਹ\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "%s ਪਰੋਫਾਇਲ ਵਿੱਚ ਗਲਤੀ, ਲੋਡ ਕਰਨ ਲਈ ਫੇਲ੍ਹ\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "%s: regex ਪੋਸਟ-ਪਰੋਸੈਸ ਦੌਰਾਨ ਗਲਤੀਆਂ ਮਿਲੀਆਂ। ਅਧੂਰਾ ਖਤਮ।\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "%s:ਪੋਸਟ-ਪਰੋਸੈਸਿੰਗ ਰੂਲ ਜੋੜਨ ਦੌਰਾਨ ਗਲਤੀਆਂ ਮਿਲੀਆਂ। ਅਧੂਰਾ ਛੱਡਿਆ।\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/cy.po0000644000175000017500000005100313502024172014071 0ustar jjjj# Welsh message file for YaST2 (@memory@). # Copyright (C) 2005 SUSE Linux Products GmbH. # Copyright (C) 2003 SuSE Linux AG. # Kevin Donnelly , 2003. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 22:14+0000\n" "Last-Translator: Kevin Donnelly \n" "Language-Team: Welsh \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: cy\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/fi.po0000644000175000017500000006334413502024172014067 0ustar jjjj# translation of apparmor-parser.fi.po to suomi # translation of apparmor-parser.fi.po to # translation of apparmor-parser.po to # translation of subdomain-parser.po to # This file is distributed under the same license as the PACKAGE package. # Copyright (C) YEAR Immunix, Inc. # # Jyri Palokangas , 2005, 2006. # Ilkka Pirskanen , 2005. # Jyri Palokangas , 2007. # Mikko Piippo , 2008. # Jyri Palokagas , 2008. # Sami Ojanen , 2008. msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2014-05-01 19:38+0000\n" "Last-Translator: Jiri Grönroos \n" "Language-Team: Suomi \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: fi\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Virhe: Muisti loppui.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Virhe: kantahakemisto %s ei ole hakemisto, ohitetaan.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Virhe: Hakemistoa %s ei voitu lisätä etsintäpolkuun.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Virhe: Muistin varaaminen epäonnistui.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Väärä kirjoituskohta\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Ei käyttöoikeutta\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Muisti loppui\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profiili ei noudata yhteyskäytäntöä\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profiili ei täsmää allekirjoitukseen\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Profiilin versio ei ole AppArmor-moduulin tukema\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profiili on jo olemassa\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profiilia ei ole olemassa\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "Tuntematon virhe (%d): %s\n" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: \"%s\" lisäys ei onnistunut. " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: \"%s\" korvaus ei onnistunut. " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: \"%s\" poisto ei onnistunut. " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Kirjoittaminen stdout-tulostusvirtaan ei onnistunut\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: Virheellinen valinta: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "%s lisäys onnistui.\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "%s korvaus onnistui.\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "\"%s\" poisto onnistui.\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PANIIKKI viallinen lisäyspuskuri %p pos %p ext %p koko %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Ei voitu avata %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Muistinvarausvirhe: Ei voitu poistaa ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Muistivarausvirhe. Ei voitu poistaa %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "työalueen luominen ei onnistunut\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "profiilin %s sarjallistaminen ei onnistunut\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Koko profiilimerkinnän kirjoittaminen ei onnistunut\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Löytyi odottamaton merkki: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) Löytyi odottamaton merkki: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: Muistin varaaminen alitoimialuepohjan liitoskohdalle ei onnistunut\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Varoitus: ei löydetä sopivaa tiedostojärjestelmää kohteesta %s, onko osio " "liitetty?\n" "Käytä --subdomainfs ohittaaksesi.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Ohjelman suorittamiseen tarvitaan pääkäyttäjän oikeudet.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Varoitus! Olet asettanut ohjelman setuid-tiedon pääkäyttäjäksi.\n" "Kaikki, jotka voivat suorittaa tämän ohjelman, voivat muuttaa AppArmor-" "profiileja.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Virhe: Ei voitu lukea profiilia %s: %s\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Muistivarausvirhe." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Tiedostosta löytyi virheitä. Keskeytetään.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Isoilla kirjoitetut määritteet \"RWLIMX\" eivät ole suositeltavia. Ole hyvä " "ja korjaa ne pienellä kirjoitetuiksi.\n" "Lue apparmor.d(5) manuaalisivu jos haluat aiheesta lisätietoja.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Ristiriita 'a' ja 'w' oikeudet ovat toisensa pois sulkevia." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Exec-valitsin 'i' virheellinen, ristiriitainen valitsin mainittu aiemmin" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "Vapaa exec-valitsin (%c%c) sallii joidenkin vaarallisten ympäristömuuttujien " "lähettämisen varmistamattomille prosesseille; man 5 apparmor.d jos haluat " "lisätietoja aiheesta.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Exec-valitsin '%c' virheellinen, ristiriidan aiheuttava valitsin määritetty " "jo aiemmin" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Exec-valitsin '%c%c' virheellinen, ristiriidan aiheuttava valitsin " "määritetty jo aiemmin" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Sisäinen: odottamaton tila merkki '%c' syötteessä" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Sisäinen virhe, aiheuttaja virheellinen määritys 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "AppArmor parser -virhe: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Merkintöjä ei voitu yhdistää. Muisti loppui\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Ei voitu luoda aliasta %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "Profiilin lippu 'debug' ei ole enää kelvollinen." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Virheellinen profiilin lippu: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Assert: `rule' palautti NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Virheellinen tila, kieltosäännöissä valitsinta 'x' ei saa edeltää valitsin " "'i', 'p' tai 'u'" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Virheellinen tila, valitsinta 'x' pitää edeltää valitsin 'i', 'p', 'c' tai " "'u'" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Virheellinen tila, valitsinta 'x' pitää edeltää valitsin 'i', 'p' tai 'u'" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Assert: `network_rule' palautti virheellisen protokollan." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Assert: `change_profile' palautti NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Assert: 'hat rule' palautti NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Assert: 'local_profile rule' palautti NULL." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Asettamaton boolean muuttuja %s käytössä if-lausekkeessa" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "turvaton sääntö suoritusoikeudet puuttuvat" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "aliryhmää voidaan käyttää vain linkkisäännöissä." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" "linkki ja suoritusoikeudet ristiriidassa tiedostossa, joka käyttää ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "linkkioikeuksia ei sallita nimetyssä profiilinsiirrossa\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "puuttuuko rivin lopetinmerkki? (merkintä: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Virheellinen verkkomerkintä." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Virheellinen kyky %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: Virheellinen aloittava {, sisäkkäiset ryhmitykset ei sallittu\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: Säännöllisen lausekkeen ryhmitysvirhe: Virheellinen määrä alkioita {} " "välissä\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Säännöllisen lausekkeen ryhmitysvirhe: Virheellinen lopettava }, " "vastaavaa aloittavaa { ei tunnistettu\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Regex-ryhmitysvirhe: Sulkematon ryhmitys tai merkkiluokka, odotetaan " "sulje } -merkintää\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Sisäisen puskurin ylivuoto, ylitettiin %d merkkiä\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Syöterivin '%s' koostaminen ei onnistunut\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" "VIRHE yhdistettäessä profiilin %s sääntöjä, lataaminen ei onnistunut\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "VIRHE profiili %s sisältää menettelytapaelementtejä, jotka eivät toimi tämän " "ytimen kanssa:\n" "\t'*', '?', merkkialueet ja muunnokset eivät ole sallittuja.\n" "\t'**' voidaan käyttää vain säännön lopussa.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" "VIRHE käsiteltäessä profiilin %s säännöllisiä lausekkeita, lataaminen ei " "onnistunut\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" "VIRHE laajennettaessa muuttujia profiilille %s, lataaminen ei onnistunut\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "VIRHE lisättäessä hattua profiilin %s käyttösääntöön\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "VIRHE profiilissa %s, lataaminen ei onnistunut\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: Löydettiin virheitä jälkikäsittelyssä. Keskeytetään.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" "%s: Löydettiin virheitä säännöllisten lausekkeiden jälkikäsittelyssä. " "Keskeytetään.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: Löydettiin virheitä jälkikäsittelyssä. Keskeytetään.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Löydettiin virheitä yhdistyssääntöjen jälkikäsittelyssä. Keskeytetään.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/sq.po0000644000175000017500000005115513502024172014111 0ustar jjjj# Albanian translation for apparmor # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 23:20+0000\n" "Last-Translator: Vilson Gjeci \n" "Language-Team: Albanian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: sq\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Leja u mohua\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Nuk ka më kujtesë\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "Nuk mund të hapim '%s'" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/cs.po0000644000175000017500000006215413502024172014074 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 02:07+0000\n" "Last-Translator: Novell Language \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: cs\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Chyba: Nedostatek paměti\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Chyba: Základní adresář %s není adresář, přeskakuje se.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Chyba: Adresář %s nelze přidat ke hledané cestě.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Chyba: Nelze přidělit paměť\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Špatná pozice zápisu\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Oprávnění odepřeno\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Nedostatek paměti\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profil neodpovídá protokolu\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profil neodpovídá podpisu\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Modul Apparmor nepodporuje verzi profilu.\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profil již existuje\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profil neexistuje\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Nelze přidat \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Nelze nahradit \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Nelze odstranit \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: nelze zapisovat na standardní výstup\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: neplatná volba: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Přidání uspělo pro \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Nahrazení uspělo pro \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Odstranění uspělo pro \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PANIKA: chybný přírůstkový buffer %p pos %p ext %p size %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Nelze otevřít %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Chyba alokace paměti: není možné odebrat ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Chyba alokace paměti: není možné odebrat %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "nelze vytvořit pracovní oblast\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "nelze serializovat profil %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Nelze zapsat celý záznam profilu\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Nalezen neočekávaný znak: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(režim_sítě) Nalezen neplatný znak: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: Nelze alokovat paměť pro bod připojení subdomainbase\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Upozornění: Nelze nalézt vhodný souborový systém v %s, je připojen?\n" "Možnost lze přepsat pomocí možnosti --subdomainfs.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Ke spuštění tohoto programu jsou třeba práva správce.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Upozornění: Hodnota setuid tohoto programu byla nastavena na uživatele " "root.\n" "Kdokoliv může spustit tento program, může aktualizovat profily modulu " "AppArmor.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Chyba: Nelze číst profil %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Chyba alokace paměti." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Chyby v souboru. Ukončuji.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Kvalifikátory velkými písmeny \"RWLIMX\" jsou zastaralé, převeďte je na malá " "písmena.\n" "Podrobnosti naleznete v manuálové stránce apparmor.d(5).\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Oprávnění 'a' a 'w' se vzájemně vylučují." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Exec kvalifikátor 'i' je neplatný, byl již specifikován konfliktní " "kvalifikátor" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "Neomezený kvalifikátor spuštění (%c%c) umožňuje, že jsou neomezenému procesu " "předány některé nebezpečné proměnné prostředí. Podrobnosti uvádí manuálová " "stránka 'man 5 apparmor.d'.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Kvalifikátor spuštění '%c' je neplatný, již byl zadán konfliktní " "kvalifikátor." #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Exec kvalifikátor '%c%c' je neplatný, byl již specifikován konfliktní " "kvalifikátor" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Vnitřní: Neznámý znak režimu '%c' na vstupu." #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Vnitřní chyba způsobila neplatné perm 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "Chyba parseru AppArmor: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Nelze sloučit záznamy. Nedostatek paměti\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Nelze vytvořit alias %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "Příznak profilu 'debug' již není platný." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Neplatný příznak profilu: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Assert: `rule' vrátil NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Neplatný režim, před 'x' musí být exec kvalifikátor 'i', 'p' nebo 'u'" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Neplatný režim, před 'x' musí být exec kvalifikátor 'i', 'p', 'c' nebo 'u'" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "Neplatný režim, před 'x' musí být kvalifikátor 'i', 'p' nebo 'u'." #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Assert: `pravidlo_sítě' vrací neplatný protokol." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Assert: `změna_profilu' vrátila hodnotu NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Assert: 'hat rule' vrátil NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Assert: 'local_profile rule' vrátil NULL." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Ve výrazu 'if' byla použita nenastavená booleovská proměnná %s." #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "nebezpečné pravidlo nemá oprávnění ke spuštění" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "podskupina může být použita pouze s pravidly odkazů." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "link a exec perms konflikt souboru pravidel používajícím ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "link perms nejsou povoleny na přechodu pojmenovaného profilu.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "chybí znak konce řádku? (záznam: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Neplatná položka sítě." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Neplatná schopnost %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: nepovolená otvírací {, vnořené seskupování není povoleno\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "%s: Chyba seskupování regex: neplatný počet položek mezi {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Chyba seskupování regex: neplatná uzavírací }, nenalezena odpovídající " "otevírací {\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Chyba seskupování regulárního výrazu: Neuzavřené seskupování nebo třída " "znaků, očekává se koncová závorka }.\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Detekováno vnitřní přetečení zásobníku, přesáhlo %d znaků\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Nelze analyzovat vstupní řádku '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" "CHYBA při slučování pravidel profilu %s, došlo k chybě při načítání.\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "CHYBOVÝ profil %s obsahuje prvky zásad, které nelze použít s tímto jádrem:\n" "\t'*', '?', rozsahy znaků a střídání nejsou povoleny.\n" "\t'**' lze použít pouze na konci pravidla.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" "CHYBA při zpracování regulárních výrazů pro profil %s, došlo k chybě při " "načítání.\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" "CHYBA při rozšíření proměnných pro profil %s, došlo k chybě při načítání.\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "Chyba při přidání pravidla pro přístup k hat pro profil %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "CHYBA v profilu %s, selhalo načítání\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: Nalezeny chyby během postprocesingu. Ukončuji.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" "%s: Nalezeny chyby během postprocesingu regulárního výrazu. Ukončuje se.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: Nalezeny chyby během postprocesingu. Ukončuji.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Nalezeny chyby při postprocesingu kombinačních pravidel. Ukončuji.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/gu.po0000644000175000017500000005712313502024172014102 0ustar jjjjmsgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 02:03+0000\n" "Last-Translator: Priyavert \n" "Language-Team: AgreeYa Solutions\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: gu\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "અયોગ્ય લેખન સ્થિતિ\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "પરવાનગી નાકબૂલ\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "અપૂરતી મેમરી\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "પ્રોફાઈલ પ્રોટોકોલ સાથે બંધબેસતો નથી\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "પ્રોફાઈલ સહી સાથે અનુરૂપ નથી\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "પ્રોફાઈલ અસ્તિત્વમાં છે\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "પ્રોફાઈલ અસ્તિત્વમાં નથી\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: ઉમેરી શકાતું નથી \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: બદલી શકાતું નથી \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: દૂર કરી શકાતું નથી \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: stdout પર શકાતું નથી\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: આગ્રહ રાખો: અયોગ્ય વિકલ્પ: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "ઉમેરવાનું સફળ થયું છે \"%s\" માટે.\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "બદલવાનું સફળ થયું છે \"%s\" માટે.\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "દૂર કરવાનું સફળ થયું છે \"%s\" માટે.\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "ભયભીત અયોગ્ય ઈન્ક્રીમેન્ટ બફર %p pos %p ext %p સાઈઝ %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "ખુલી શક્તું નથી %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "કાર્યનો વિસ્તાર બનાવી શકાતો નથી\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "પ્રોફાઈલ પ્રકાશિત થઈ શકતો નથી %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: સંપૂર્ણ પ્રોફાઈલ એન્ટ્રી લખી શકાતી નથી.\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "અણધાર્યો વર્ણ મળ્યો: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: સબડોમેઈનબેઝ માઉન્ટ પોઈન્ટ માટે મેમરી ફાળવી શકાઈ નહીં\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "મેમરી ફાળવવામાં ભૂલ." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: ફાઈલમાં ભૂલો મળી છે. અટકાવાયું છે.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Exec ક્વોલીફાયર 'i' અયોગ્ય છે, વિરોધ કરતો ક્વોલીફાયર જણાવી દેવામાં આવ્યો જ છે" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "એન્ટ્રીઓ ભળી શકાઈ નથી. અપૂરતી મેમરી\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "આગ્રહ રાખો: `રૂલ' પાછો લાવ્યો નલ NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "આગ્રહ રાખો: `હેટ રૂલ' પાછો લાવ્યો નલ NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "લાઈન પૂરી થયા પછીનો વર્ણ ખૂટે છે? (એન્ટ્રી: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: ગેરકાયદેસર ઓપન {, નેસ્ટિંગ ગ્રુપીંગ ને મંજૂરી નથી\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "%s: Regex ગ્રુપીંગ ભૂલ: {} ની વચ્ચે અયોગ્ય સંખ્યાની બાબતો\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Regex ગ્રુપીંગ ભૂલ: અયોગ્ય બંધ }, તેને અનુરૂપ કોઈ ઓપન { ન્થી મળતું\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: આંતરિક બફર ઉભરાઈ ગયેલું મળે છે, %d વર્ણો ઓળંગાઈ ગયા છે\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: ઈન્પુટ લાઈન '%s' પાર્સ કરી શકાતી નથી\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "પ્રોફાઈલ %s માં ભૂલ, લઈ આવવાનું નિષ્ફળ\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "%s: પોસ્ટપ્રોસેસીંગ નિયમો ભેગાં કરતાં ભૂલો મળી છે. અટકાવાયું છે.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/mk.po0000644000175000017500000005101213502024172014065 0ustar jjjj# Macedonian message file for YaST2 (@memory@). # Copyright (C) 2006 SUSE Linux Products GmbH. # Зоран Димовски # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 22:27+0000\n" "Last-Translator: Зоран Димовски \n" "Language-Team: Macedonian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: mk\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/it.po0000644000175000017500000007160313502024172014102 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2014-10-26 18:14+0000\n" "Last-Translator: Claudio Arseni \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: it\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Errore: memoria esaurita.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Errore: la directory di base %s non è una directory, ignorata.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" "Errore: impossibile aggiungere la directory %s al percorso di ricerca.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Errore: impossibile allocare memoria.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Posizione di scrittura errata\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Permesso negato\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Memoria esaurita\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "Impossibile copiare il profilo: indirizzo di memoria errato\n" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Il profilo non è conforme al protocollo\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Il profilo non corrisponde alla firma\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Versione del profilo non supportata dal modulo Apparmor\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profilo già esistente\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profilo inesistente\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" "Permesso non consentito: tentativo di caricare un profilo con i limiti " "applicati?\n" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "Errore sconosciuto (%d): %s\n" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Impossibile aggiungere \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Impossibile sostituire \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Impossibile rimuovere \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Impossibile scrivere su stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "%s: impossibile scrivere sul file di output\n" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERZIONE: opzione non valida: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Aggiunta riuscita per \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Sostituzione riuscita per \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Rimozione riuscita per \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "ATTENZIONE buffer incremento errato %p pos %p est %p dimensione %d ris %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "regole di rete del profilo %s non applicate\n" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "Tipo di modello sconosciuto\n" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Impossibile aprire %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Errore di allocazione memoria: impossibile rimuovere ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Errore di allocazione memoria: impossibile rimuovere %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "impossibile creare area di lavoro\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "impossibile serializzare profilo %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: impossibile scrivere l'intera voce del profilo\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "%s: impossibile scrivere l'intero profilo nella cache\n" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "Impossibile aprire \"%s\"" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "fstat non riuscita per \"%s\"" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "opendir non riuscita per \"%s\"" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "stat non riuscita per \"%s\"" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "Impossibile aprire \"%s\" in \"%s\"" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Trovato carattere imprevisto: \"%s\"" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "La dichiarazione di variabile non accetta virgole terminanti" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) Trovato carattere imprevisto: \"%s\"" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "Avviso da %s (%s%sriga %d): %s" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: impossibile allocare memoria per il punto di montaggio base " "sottodominio\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Avviso: impossibile trovare un fs adatto in %s. È effettivamente montato?\n" "Per ignorare, utilizzare -subdomainfs.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: errore. Sono richiesti privilegi di root per eseguire questo programma.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: attenzione. È stato impostato il root setuid di questo programma.\n" "Chiunque possa eseguire questo programma può aggiornare i profili di " "AppArmor.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Errore: impossibile leggere il profilo %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Errore allocazione memoria." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "Caricamento cache eseguito con successo per \"%s\".\n" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "Ricaricamento cache eseguito con successo per \"%s\".\n" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: errori individuati nel file. Interruzione.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Qualificatori maiuscoli \"RWLIMX\" obsoleti, utilizzare caratteri " "minuscoli.\n" "Per dettagli, consultare la manpage di apparmor.d(5).\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Conflitto: i permessi \"a\" e \"w\" si escludono a vicenda." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Qualificatore Exec \"i\" non valido: qualificatore in conflitto già " "specificato" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "Il qualificatore Exec senza limitazioni (%c%c) consente il passaggio di " "alcune variabili d'ambiente pericolose al processo senza limitazioni; " "consultare \"man 5 apparmor.d\" per dettagli.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Qualificatore Exec \"%c\" non valido: qualificatore in conflitto già " "specificato." #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Il qualificatore exec \"%c%c\" non è valido: qualificatore in conflitto è " "già specificato" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Interno: carattere modalità imprevisto \"%c\" nell'input" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Un errore interno ha generato un permesso non valido 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "Errore parser AppArmor: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Impossibile unire le voci: memoria esaurita\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "profilo %s: ha regole unite %s con modificatori x in conflitto\n" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "L'allegato profilo deve iniziare con \"/\"." #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" "I nomi di profili devono iniziare con \"/\", namespace o le parole chiavi " "\"profile\" o \"hat\"." #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Creazione dell'alias %s -> %s non riuscita\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" "La flag del profilo chroot_relative va in conflitto con namespace_relative" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" "La flag mediate_deleted del profilo va in conflitto con delegate_deleted" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" "La flag attach_disconnected del profilo va in conflitto con " "no_attach_disconnected" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" "La flag chroot_attach del profilo va in conflitto con chroot_no_attach" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "La flag \"debug\" del profilo non è più valida." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Flag del profilo non valida: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Asserzione: \"rule\" ha restituito NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Modalità non valida. Nelle regole di divieto \"x\" non deve essere preceduto " "dal qualificatore exec \"i\", \"p\" o \"u\"" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Modalità non valida. \"x\" deve essere preceduto dal qualificatore exec " "\"i\", \"p\", \"c\" o \"u\"" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Modalità non valida. \"x\" deve essere preceduto dal qualificatore Exec " "\"i\", \"p\" o \"u\"." #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Asserzione: \"network_rule\" ha restituito un protocollo non valido." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Asserzione: \"change_profile\" ha restituito NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Asserzione: \"hat rule\" ha restituito NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Asserzione: \"local_profile rule\" ha restituito NULL." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Variabile booleana %s non impostata usata in espressione if." #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "autorizzazioni esecuzione mancanti per regola non sicura." #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" "sottoinsieme può essere usato solamente con le regole dei collegamenti." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" "le autorizzazioni link ed exec sono in conflitto con le regole definite nel " "file che utilizza ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" "non è possibile usare collegamenti permanenti nella transizione del profilo " "nominato.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "un carattere di fine riga mancante? (voce: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Voce di rete non valida." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Funzionalità non valida %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "Errore di analisi di AppArmor per %s%s%s alla riga %d: %s\n" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "Errore di analisi di AppArmor, %s%s riga %d: %s\n" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" "%s: parantesi {di apertura non valida, annidamento raggruppamenti non " "consentito\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: errore raggruppamento regex: numero di elementi non valido tra {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: errore raggruppamento regex: parentesi } di chiusura non valida, non è " "stata individuata alcuna { aperta\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: errore raggruppamento regex: raggruppamento non chiuso o classe " "caratteri, chiusura prevista }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: individuato overflow del buffer interno, superati %d caratteri\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: impossibile analizzare la riga input \"%s\"\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" "%s: nome \"%s\" del profilo non valido - espressione regolare non corretta\n" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" "ERRORE nell'unione delle regole per il profilo %s, caricamento non riuscito\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "ERRORE: il profilo %s contiene elementi di norme non utilizzabili con questo " "kernel:\n" "\t\"*\", \"?\", intervalli di caratteri e alternanze non consentiti.\n" "\t\"**\" utilizzabili solo alla fine di una regola.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" "ERRORE nell'elaborazione di regex per il profilo %s, caricamento non " "riuscito\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" "ERRORE nell'espansione delle variabili per il profilo %s, caricamento non " "riuscito\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" "ERRORE durante l'aggiunta di una regola di accesso hat per il profilo %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "ERRORE nel profilo %s, caricamento non riuscito\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: rilevati errori durante la post-elaborazione. Interruzione.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" "%s: individuati errori durante la post-elaborazione regex. Interruzione.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: rilevati errori durante la post-elaborazione. Interruzione.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: individuati errori durante la post-elaborazione della combinazione delle " "regole. Interruzione.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "Impossibile elaborare inclusione directory \"%s\" in \"%s\"" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "Buffer feature pieno." #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "Memoria esaurita" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "Impossibile creare la directory di cache: %s\n" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "File nel percorso della directory di cache: %s\n" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "Impossibile aggiornare la directory di cache: %s\n" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "Interno: modalità caratteri DBus \"%c\" inaspettata in ingresso" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "Un errore interno ha generato un permesso DBus non valido 0x%x\n" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "prefisso di negazione non consentito" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "prefisso proprietario non consentito" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "prefisso proprietario non consentito nelle regole di montaggio" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "prefisso proprietario non consentito nelle regole dbus" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "prefisso proprietario non consentito nelle regole di funzionalità" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "montaggio condizionale non valido %s%s" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "regola di montaggio errata" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "condizioni punti di montaggio attualmente non supportati" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "condizionale pivotroot \"%s\" non valido" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" "%s: errore raggruppamento espressione regolare: parentesi ] di chiusura non " "valida, corrispondente apertura [ non trovata\n" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" "%s: errore raggruppamento espressione regolare: superata nidificazione " "massima di {}\n" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" "ERRORE elaborazione regole policydb per il profilo %s, caricamento non " "riuscito\n" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" "ERRORE sostituzione alias per il profilo %s, caricamento non riuscito\n" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "%s: impossibile scrivere %s\n" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" "Errore: impossibile leggere il profilo binario o il file cache %s: %s.\n" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "Errore: impossibile leggere il file di cache \"%s\", saltato...\n" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "Interno: carattere %s di modalità inatteso nell'input \"%c\"" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "Un errrore interno ha generato un permesso %s non valido 0x%x\n" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "prefisso proprietario non consentito nelle regole di montaggio" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "prefisso proprietario non consentito nele regole dbus" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "prefisso proprietario non consentito nelle regole di segnale" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "prefisso proprietario non consentito nelle regole ptrace" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "prefisso proprietario non consentito nelle regole unix" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "prefisso proprietario non consentito nelle regole di capacità" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "regola dbus: gruppo condizionale %s=() non valido" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "regola unix: gruppo condizionale %s=() non valido" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "%s: errore regex: carattere di escape \"\\\" terminante\n" apparmor-2.13.3/parser/po/si.po0000644000175000017500000005064313502024172014102 0ustar jjjj# Sinhala message file for YaST2 (@memory@). # Copyright (C) 2007 SUSE Linux Products GmbH. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 22:30+0000\n" "Last-Translator: i18n@suse.de\n" "Language-Team: Sinhala \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: si\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/en_CA.po0000644000175000017500000005111613502024172014430 0ustar jjjj# English (Canada) translation for apparmor # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 22:00+0000\n" "Last-Translator: AppArmor list \n" "Language-Team: English (Canada) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: en_CA\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/bs.po0000644000175000017500000005320113502024172014064 0ustar jjjj# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2014-05-01 19:36+0000\n" "Last-Translator: Samir Ribić \n" "Language-Team: Bosnian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: bs\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Greška: Nema više memorije.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Greška: osnovni direktorij %s nije direktorij, preskačem.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Greška: Ne mogu dodati direktorij %s u stazu koja se traži.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Greška: Ne mogu alocirati memoriju.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Neipravan položaj za zapisivanje\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Odobrenje odbijeno\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Nedostaje mi slobodne memorije\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "Ne mogu kopirati profil: Loša memorijska adresa\n" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profil ne odgovara protokolu\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profil ne odgovara potpisu\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Verzija profila nije podržana Apparmor modulom\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profil već postoji\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profil ne postoji\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "Dozvola odbijena; pokušao da učita profil, dok je zatvoren?\n" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "Nepoznata greška (%d): %s\n" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Ne mogu dodati \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Ne mogu zamijeniti \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s : Ne mogu ukloniti \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Ne mogu pisati na stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "%s: Ne mogu pisati u izlaznu datoteku\n" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: PROVJERA: Neispravan izbor: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Dodavanje je uspjelo za \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Zamjena je uspjela za \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Uklanjanje je uspjelo za \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "PANIKA neispravan inkrementalni spremnik %p pol %p ekst %p vel %d raz %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "profil %s mrežna pravila nisu primijenjena\n" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "Nepoznat tip uzorka\n" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Ne mogu otvoriti %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Greška memorijske alokacije: Ne mogu ukloniti ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Greška memorijske alokacije: Ne mogu ukloniti %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/gl.po0000644000175000017500000005131513502024172014066 0ustar jjjj# Galician message file for YaST2 (@memory@). # Copyright (C) 2005 SUSE Linux Products GmbH. # Copyright (C) 2000, 2001 SuSE GmbH. # Copyright (C) 2002 SuSE Linux AG. # Jesús Bravo Álvarez , 2000. # # Proxecto Trasno - Adaptación do software libre á lingua galega: Se desexas # colaborar connosco, podes atopar máis información en http://trasno.gpul.org # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 02:24+0000\n" "Last-Translator: Christian Boltz \n" "Language-Team: Galician \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: gl\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/mr.po0000644000175000017500000005704013502024172014103 0ustar jjjjmsgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 02:17+0000\n" "Last-Translator: Priyavert \n" "Language-Team: AgreeYa Solutions \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: mr\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "लिहिण्याची वाईट स्थिती\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "परवानगी नाकारली\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "स्मृती संपली\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "प्रोफाइल प्रोटोकॉलशी सुसंगत नाही\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "प्रोफाईल स्वाक्षरीशी जुळत नाही\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "प्रोफाईल आधीच अस्तित्वात आहे\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "प्रोफाईल अस्तित्वात नाही\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: \"%s\" घालणे अशक्य. " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: \"%s\"बदलणे अशक्य. " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: \"%s\"काढून टाकणे अशक्य. " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: stdoutला लिहिणे अशक्य\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: अवैध पर्याय: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "\"%s\"साठी अडिशन यशस्वी.\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "\"%s\"साठी बदली यशस्वी.\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "\"%s\"काढून टाकण्याची क्रिया यशस्वी.\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PANIC बॅड इन्क्रिमेंट बफर %p pos %p ext %p साईझ %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "%s - %s उघडणे अशक्य\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "कामाचे क्षेत्र निर्माण करणे अशक्य\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "प्रोफाईल %s ची क्रमवारी लावणे अशक्य\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: संपूर्ण प्रोफाइल प्रविष्टी लिहिणे अशक्य\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "अनपेक्षित वर्ण: '%s' आढळला" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: सबडोमेन माऊंट पॉईंटसाठी स्मृती वाटून देता आली नाही\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "स्मृती वाटून देण्यात चूक." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: फाईलमधे चुका आढळल्या. सोडून देत आहे.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "Exec क्वालिफायर 'i' अवैध, विवादास्पद क्वालिफायर आधीच नमूद केलेला आहे" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "प्रविष्टी विलीन करता आल्या नाहीत. स्मृती संपली\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "असर्ट: `रुल' NULL परत आला." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "असर्ट: 'हेट रुल' NULL परत आला." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "ओळीच्या अखेरचा वर्ण गायब? (प्रविष्टी: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: {, बेकायदेशीररित्या उघडला, नेस्टींग समुह करण्यास अनुमती नाही\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "%s: Regex समुह करण्यात चूक: अवैधपणे {} दरम्यान अनेक अवैध आयटेम्स.\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Regex समुह करण्यात चूक: अवैधपणे }, बंद, कोणताही जुळणारा{ आढळला नाही\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: अंतर्गत बफर भरुन वाहू लागल्याचे आढळले, %d पार्से करणे अशक्य\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: इनपुट लाईन '%s' पार्से करणे अशक्य\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "प्रोफाईल %s मधे चुक, लोड करण्यात अपयश\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: नियमांचे पोस्ट प्रोसेसिंग एकत्र करण्यात चूक आढळली. सोडून देत आहे.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/nl.po0000644000175000017500000006217713502024172014105 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 03:24+0000\n" "Last-Translator: Novell Language \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: nl\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Fout: Geheugen vol\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Fout: basedir %s is geen map en wordt overgeslagen.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Fout: kan directory %s niet toevoegen aan zoekpad.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Fout: Geheugen vol\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Foutieve schrijfpositie\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Rechten geweigerd\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Geheugen vol\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profiel is niet in overeenstemming met het protocol\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profiel komt niet overeen met de ondertekening\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Profielversie wordt niet ondersteund door de AppArmor-module\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profiel bestaat al\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profiel bestaat niet\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Niet in staat om \"%s\" toe te voegen. " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Niet in staat om \"%s\" te vervangen. " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Niet in staat om \"%s\" te verwijderen. " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Niet in staat om naar stdout te schrijven\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: BEWERING: Ongeldige optie: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Toevoeging geslaagd voor \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Vervanging geslaagd voor \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Verwijdering geslaagd van \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "PANIEK: Foutieve verhoging van de buffer %p pos %p ext %p size %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Kan %s - %s niet openen\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Geheugenreserveringsfout: kan ^%s niet verwijderen\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Geheugenreserveringsfout: kan %s:%s niet verwijderen." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "Kan geen werktruimte aanmaken\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "Kan profiel %s niet bewerken\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Het gehele profiel kon niet opgeslagen worden\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Onverwacht teken gevonden: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) Onverwacht teken gevonden: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: Kon geen geheugen reserveren voor het subdomeinbasis aankoppelpunt\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Waarschuwing: kan geen geschikt bestandssysteem vinden in %s. Is het wel " "gekoppeld?\n" "Gebruik --subdomainfs om te negeren.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: U hebt privileges voor de root nodig als u dit programma wilt " "uitvoeren.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Waarschuwing! U hebt dit programma systeembeheerrechten gegeven (setuid " "root).\n" "Iederen die dit programma kan uitvoeren, kan ook uw AppArmor-profielen " "bijwerken.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Fout: kan profiel %s niet lezen: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Fout in geheugenreservering." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Fouten gevonden in het bestand. Stop.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Bepalingen met hoofdletters \"RWLIMX\" worden niet meer gebruikt. Gebruik " "kleine letters\n" "Kijk op de apparmor.d(5)-manpage voor meer informatie.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Conflict: combinaties met 'a' en 'w' gaan niet samen." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Exec bepaling 'i' ongeldig, conflicterende bepaling is reeds opgegeven" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "Onbegrensde exec-bepaling (%c%c) staat toe dat sommige gevaarlijke " "omgevingsvariabelen worden doorgegeven aan het onbegrensde proces; bekijk '5 " "apparmor.d' voor meer informatie.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Exec-bepaling '%c' is ongeldig. Er is al een conflicterende bepaling " "opgegeven." #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Exec-bepaling '%c%c' ongeldig; een bepaling, waar deze mee botst, is reeds " "opgegeven" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Intern: onverwacht modusteken '%c' in invoer" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Interne fout genereerde ongeldige permissie 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "Fout in AppArmor-parser: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Kan items niet samenvoegen. Onvoldoende geheugen\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Kan alias %s -> %s niet aanmaken\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "Profielvlag 'debug' is niet langer geldig." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Ongeldige profielvlag %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Bewering: `rule' gaf NULL terug." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Ongeldige modus, in weigerregels moet 'x' voorafgegaan worden door exec-" "bepaling 'i', 'u' of 'p'" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Ongeldige modus, 'x' moet voorafgegaan worden door exec-bepaling 'i', 'c', " "'u' of 'p'" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Ongeldige modus. 'x' moet worden voorafgegaan door exec-bepaling 'i', 'p' of " "'u'." #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Bewering: 'network_rule' heeft ongeldig protocol geretourneerd." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Bewering: 'change_profile' heeft NULL geretourneerd." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Bewering: `hat rule' gaf NULL terug." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Bewering: `local_profile' gaf NULL terug." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" "Niet-ingestelde booleaanse variabele %s wordt gebruikt in if-expressie" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "onveilige regel ontbrekende exec-machtigingen" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "Subset kan alleen worden gebruikt met linkregels." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" "Link- en exec-permissies conflicteren op een bestandsregel die -> gebruikt" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" "Link-permissies zijn niet toegestaan bij het transporteren van een profiel " "met een naam.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "Ontbreekt een regeleindeteken? (invoer: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Ongeldig netwerkitem." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Ongeldige functie %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: Ongeldige open {, het nesten van groepen is niet toegestaan\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "%s: Regex groepfout: Ongeldig aantal tussen {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Regex groepfout: Ongeldige close }, geen bijbehorende open { gevonden\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Fout bij groeperen reguliere expressies: ongesloten groepen of " "tekencategorie, terwijl sluiting wordt verwacht }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Interne buffer overschreden, %d tekens teveel\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Niet in staat om regel '%s' te verwerken\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" "FOUT bij het samenvoegen van regels voor profiel %s. Kan niet laden\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "FOUT profiel %s bevat beleidselementen die niet kunnen worden gebruikt met " "deze kernel:\n" "\t'*', '?', tekenbereiken en alternaties zijn niet toegestaan.\n" "\t'**' mag alleen worden gebruikt aan het eind van een regel.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" "FOUT bij het verwerken van reguliere expressies voor profiel %s. Kan niet " "laden\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "FOUT bij variabelen uitbreiden voor profiel %s. Kan niet laden\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "FOUT bij toevoegen van de hat-toegangregel voor profiel %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "FOUT in profiel %s, laden mislukt\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: fouten gevonden tijdens het naverwerken. Afbreken.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "%s: Fouten gevonden tijdens de nabewerking van regex regels. Stop.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: fouten gevonden tijdens de naverwerking. Stopt.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Fouten gevonden in het combineren van de nabewerkingsregels. Stop.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/bg.po0000644000175000017500000005102113502024172014046 0ustar jjjj# @TITLE@ # Copyright (C) 2006, SUSE Linux GmbH, Nuremberg # FIRST AUTHOR , YEAR. # # This file is distributed under the same license as @PACKAGE@ package. FIRST # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 22:10+0000\n" "Last-Translator: Borislav Mitev \n" "Language-Team: Bulgarian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: bg\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/hr.po0000644000175000017500000006173013502024172014077 0ustar jjjj# translation of apparmor-parser.hr.po to Croatian # Croatian message file for YaST2 (@memory@) # Copyright (C) 2005 SUSE Linux Products GmbH. # Copyright (C) 2002 SuSE Linux AG. # Copyright (C) 2001 SuSE GmbH. # # Vlatko Kosturjak , 2001. # Krešimir Jozić , 2006, 2007, 2008. msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 02:58+0000\n" "Last-Translator: Krešimir Jozić \n" "Language-Team: Croatian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: hr\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Greška: Nedovoljno memorije.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Greška: temeljni direktorij %s nije direktorij, preskačem.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Greška: Ne mogu dodati direktorij %s u putanju za pretragu.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Greška: Ne mogu rezervirati memoriju.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Neipravan položaj za zapisivanje\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Pristup odbijen\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Nema dovoljno memorije\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profil ne odgovara protokolu\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profil ne odgovara potpisu\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Verzija profila nije podržana od Apparmor modula\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profil već postoji\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profil ne postoji\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Ne mogu dodati \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Ne mogu zamijeniti \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s : Ne mogu ukloniti \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Ne mogu pisati na stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: UMETANJE: Neispravan izbor: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Dodavanje je uspjelo za \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Zamjena je uspjela za \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Uklanjanje je uspjelo za \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "PANIKA neispravan inkrementalni spremnik %p pol %p ekst %p vel %d raz %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Ne mogu otvoriti %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Greška prilikom rezervacije memorije: ne mogu ukloniti ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Greška prilikom rezervacije memorije: ne mogu ukloniti %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "Ne mogu napraviti radni prostor\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "Ne mogu serijalizirati profil %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Ne mogu zapisati cjeli unos profila\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Pronađen neočekivani znak: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) Pronađen neočekivani znak: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: Ne mogu rezervirati memoriju za točku montiranja poddomene\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Upozorenje: ne mogu pronaći prikladan datotečni sustav u %s, da li je " "montiran?\n" "Koristite --subdomainfs za premoštenje.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Ispričavamo se. Trebate root privilegije za pokretanje ovog programa.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Upozorenje! Postavili ste setuid root ovog programa.\n" "Svatko tko može pokrenuti ovaj program može manipulirati AppArmor " "profilima.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Greška: Ne mogu učitati profil %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Greška kod rezerviranja memorije." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s Pronađene su greške u datoteci. Prekidam.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Kvalifikatori s velikim slovima \"RWLIMX\" su zastarjeli, molimo vas da ih " "pretvorite u mala slova\n" "Pogledajte apparmor.d(5) man stranice za detalje.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Sukob 'a' i 'w' dozvole su međusobno isključive." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Kvalifikator izvršavanja 'i' nije ispravan, sukobljeni kvalifikator je već " "naveden" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "Neograničeni kvalifikator izvršavanja (%c%c) dozvoljava da neke opasne " "varijable okoline budu proslijeđene neprovjerenim procesima, pogledajte 'man " "5 apparmor.d' za detalje.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Kvalifikator izvršavanja '%c' nije ispravan, sukobljeni kvalifikator je već " "naveden" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Kvalifikator izvršavanja '%c%c' nije ispravan, sukobljeni kvalifikator je " "već naveden" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Unutrašnje: neočekivani oblik znaka '%c' u ulazu" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Unutrašnja greška je stvorila neispravne dozvole 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "AppArmor greška parsera: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Ne mogu spojiti unose. Nedovoljno memorije\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Ne mogu napraviti alias %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "Zastavica profila 'uklanjanje grešaka' više nije ispravna." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Neispravna zastavica profila: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Potvrda: `rule' je vratilo NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Neispravan način, u pravilima odbijanja 'x' ne smije imati kvalifikatore " "izvršavanja 'i', 'p', ili 'u' u prefiksu" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Neispravan oblik, ispred 'x' moraju biti kvalifikatori izvršavanja 'i', 'p', " "'c' ili 'u'" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Neispravan oblik, ispred 'x' moraju biti kvalifikatori izvršavanja 'i', 'p' " "ili 'u'" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Potvrda: `network_rule' je vratilo neispravan protokol." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Potvrda: `change_profile' je vratilo NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Potvrda: `hat rule' je vratilo NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Nepostavljena varijabla istinitosti %s korištena u if-uvjetu" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "Nesigurnom pravilu nedostaju prava izvršavanja" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "nedostaje oznaka kraja niza? (unos: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Neispravan mrežni unos." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Neispravna mogućnost %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: Neispravno otvaranje {, ugniježđena grupiranja nisu dozvoljena\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: Greška prilikom grupiranja regularnih izraza: Neispravan broj stavki " "između {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s Greška prilikom grupiranja regularnih izraza: Neispravno zatvaranje }, " "nema odgovarajućeg otvaranja {\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s Greška prilikom grupiranja regularnih izraza: Nezatvoreno grupiranje ili " "klasa znakova, očekujem zatvaranje }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" "%s: Detektiran je prelijev unutrašnjeg spremnika, %d znakova previše\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Ne mogu parsirati ulaznu liniju '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "GREŠKA kod spajanja pravila za profil %s, ne mogu učitati\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "GREŠKA profil %s sadrži elemente pravila koji se ne mogu korisiti s ovim " "kernelom:\n" "\t'*', '?', raspon znakova i alternative nisu dozvoljene.\n" "\t'**' se može koristiti samo na kraju pravila.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "GREŠKA kod obrade regularnih izraza za profil %s, ne mogu učitati\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "GREŠKA kod učitavanja varijabli za profil %s, ne mogu učitati\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "GREŠKA u profilu %s, ne mogu učitati\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" "%s: Nađene su greške prilikom postprocesiranja regularnih izraza. " "Prekidam.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Nađene su greške prilikom postprocesiranja kombiniranja pravila. " "Prekidam.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/es.po0000644000175000017500000006406113502024172014075 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-26 03:48+0000\n" "Last-Translator: Monkey \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: es\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Error: memoria insuficiente.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Error: el directorio base %s no es un directorio. Se va a omitir.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" "Error: no se ha podido añadir el directorio %s a la vía de búsqueda.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Error: no es posible asignar memoria.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Posición de escritura incorrecta\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Permiso denegado\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Memoria agotada\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "No se puede copiar el perfil. Dirección de memoria incorrecta\n" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "El perfil no se ajusta al protocolo\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "El perfil no coincide con la firma\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "La versión del perfil no se admite en el módulo de Apparmor.\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "El perfil ya existe\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "El perfil no existe\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" "Permiso denegado. ¿Intentando cargar un perfil mientras estaba confinado?\n" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "Error desconocido (%d): %s\n" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: no es posible añadir \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: no es posible sustituir \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: no es posible eliminar \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: no es posible escribir en stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "%s: imposible escribir en el archivo de salida\n" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: AFIRMACIÓN: Opción no válida: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Adición correcta de \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Sustitución correcta de \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Eliminación correcta de \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "PANIC: incremento de buffer incorrecto; pos %p; ext %p; tamaño %p; res %d " "%p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "perfil %s no se cumplen las reglas de red\n" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "Tipo de patrón desconocido\n" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "No es posible abrir %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Error de asignación de memoria: no se puede eliminar ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Error de asignación de memoria: no se puede eliminar %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "no es posible crear área de trabajo\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "no es posible poner en serie el perfil %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: no es posible escribir todo el perfil\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "%s: Imposible escribir la entrada de perfil completa a la caché\n" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "No se pudo abrir '%s'" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "fstat falló para «%s»" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "opendir falló «%s»" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "No se pudo abrir «%s» en «%s»" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Se ha detectado un carácter inesperado: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) Se ha encontrado un carácter inesperado: %s" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: no es posible asignar memoria para el punto de montaje de base de " "subdominio\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Advertencia: no se encuentra un sistema de archivos adecuado en %s. ¿Se ha " "montado?\n" "Use --subdomainfs para anular.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: lo sentimos, pero debe tener privilegios de usuario Root para ejecutar " "este programa.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: advertencia. Ha configurado este programa como raíz de setuid.\n" "Cualquier usuario que pueda ejecutar este programa podrá actualizar los " "perfiles de AppArmor.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Error: no se ha podido leer el perfil %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Error de asignación de memoria." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: se han detectado errores en el archivo. Cancelando.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Los calificadores en mayúscula RWLIMX han quedado obsoletos. Conviértalos a " "minúscula.\n" "Consulte la página man apparmor.d(5) para obtener detalles.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Conflicto: los permisos a y w son mutuamente excluyentes." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "El calificador de ejecución 'i' no es válido, ya se ha especificado un " "calificador en conflicto" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "El calificador de ejecución sin limitar (%c%c) permite que se pasen algunas " "variables de entorno peligrosas al proceso sin limitar; consulte man 5 " "apparmor.d para obtener detalles.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "El calificador de ejecución %c no es válido. Ya se ha especificado un " "calificador en conflicto." #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "El calificador de ejecución %c%c no es válido, ya que está en conflicto con " "un calificador ya definido." #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Interno: carácter de modo inesperado %c en la entrada" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Un error interno ha generado permisos no válidos 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "Error del analizador de AppArmor: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "No es posible fusionar las entradas. Memoria agotada\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Error al crear el alias %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "El indicador de perfil debug ya no es válido." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Indicador de perfil no válido: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Afirmación: `rule' ha devuelto NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "El modo no es válido. Las reglas de negación x no pueden ir precedidas de " "los calificadores de ejecución i, p ni u." #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "El modo no es válido. 'x' debe ir precedido de los calificadores de " "ejecución 'i', 'p', 'c' o 'u'." #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Modo no válido. x debe estar precedida del calificador de ejecución i, p o u." #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Afirmación: network_rule ha devuelto un protocolo no válido." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Afirmación: change_profile ha devuelto NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Afirmación: 'hat rule' ha devuelto NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Afirmación: la regla local_profile ha devuelto un valor nulo." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Variable booleana %s sin definir utilizada en expresión condicional." #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "Regla no segura. Faltan los permisos de ejecución." #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "Sólo se puede utilizar el subconjunto con reglas de enlace." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" "Conflicto entre los permisos de ejecución y de enlace en un archivo de " "reglas que usa ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" "No se permiten los permisos de enlace en una transición de perfil con " "nombre.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "¿Falta final de carácter de línea? (Entrada: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Entrada de red no válida." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Característica no válida %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: { de apertura ilegal, la anidación de grupos no está permitida\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: error de agrupación Regex: número de elementos entre {} no válido\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: error de agrupación Regex: } de cierre no válido, no se ha encontrado el " "signo { de apertura correspondiente\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: error de agrupación de regex. Grupo o clase de caracteres sin cerrar. Se " "esperaba } de cierre.\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" "%s: detectado desbordamiento de buffer interno, superado en %d caracteres\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: no es posible analizar la línea de entrada '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "ERROR al combinar reglas para el perfil %s. Error al cargar.\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "ERROR: el perfil %s contiene elementos de directiva que no se pueden usar " "con este núcleo:\n" "\tNo se admite '*', '?', los rangos de caracteres ni las alternancias.\n" "\t'**' sólo se puede utilizar al final de una regla.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "ERROR al procesar regexs para el perfil %s. Error al cargar.\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" "ERROR al expandir las variables para el perfil %s. Error al cargar.\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "Error al añadir la regla de acceso hat en el perfil %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "ERROR en el perfil %s, error al cargar\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: se han detectado errores durante el postprocesado. Abortando.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" "%s: se han detectado errores durante el posprocesado de regex. Cancelando.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: se han detectado errores durante el postrocesado. Abortando.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: se han detectado errores en el posprocesado de combinación de reglas. " "Cancelando.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/ar.po0000644000175000017500000006610713502024172014073 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 01:29+0000\n" "Last-Translator: Novell Language \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: ar\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "خطأ: نفدت الذاكرة.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "خطأ: basedir %s ليس دليلاً، يتم الآن التخطي.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "خطأ: تعذرت إضافة الدليل %s إلى مسار البحث.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "خطأ: تعذر تخصيص الذاكرة.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "موضع كتابة غير صالح\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "الإذن مرفوض\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "نفدت الذاكرة\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "ملف التعريف غير متوافق مع البروتوكول\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "ملف التعريف غير متوافق مع التوقيع\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "لا تدعم الوحدة النمطية Apparmor إصدار ملف التعريف\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "ملف التعريف موجود بالفعل\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "ملف التعريف غير موجود\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: تعذرت إضافة \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: تعذر استبدال \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: تعذرت إزالة \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: تعذرت الكتابة إلى stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: تأكيد: خيار غير صالح: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "نجحت الإضافة لـ \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "نجح الاستبدال لـ \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "نجحت الإزالة لـ \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "PANIC ذاكرة وسيطة للزيادة غير صالحة %p pos %p ext %p size %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "تعذر فتح %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "خطأ في تخصيص الذاكرة: تعذرت إزالة ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "خطأ في تخصيص الذاكرة: تعذرت إزالة %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "تعذر إنشاء منطقة عمل\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "تعذر تعيين تسلسل ملف التعريف %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: تعذرت كتابة إدخال ملف التعريف بالكامل\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "تم العثور على حرف غير متوقع: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) تم العثور على حرف غير متوقع: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: تعذر تخصيص ذاكرة لنقطة توصيل قاعدة المجال الفرعي\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "تحذير: تعذر العثور على نظام ملفات مناسب في %s، هل تم توصيله؟\n" "استخدم --subdomainfs لتجاوزه.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: عذرًا. يجب أن تتوفر لديك امتيازات المسؤول لكي تتمكن من تشغيل هذا " "البرنامج.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: تحذير!لقد قمت بتعيين جذر setuid لهذا البرنامج.\n" "يمكن لأي شخص يستطيع تشغيل هذا البرنامج القيام بتحديث ملفات تعريف AppArmor.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "خطأ: تعذرت قراءة ملف التعريف %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "خطأ في تخصيص الذاكرة." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: تم العثور على أخطاء في الملف. يتم الآن الإيقاف.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "يتم إهمال المؤهلات بأحرف كبيرة \"RWLIMX\"، الرجاء تحويلها إلى أحرف صغيرة\n" "راجع صفحة الدليل apparmor.d(5) للحصول على التفاصيل.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "لا يمكن استخدام الإذنين 'a' و'w' المتعارضين معًا." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "المؤهل التنفيذي 'i' غير صالح، تم تحديد مؤهل متعارض بالفعل" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "يسمح المؤهل التنفيذي غير المقيد (%c%c) بتمرير بعض متغيرات البيئة الخطيرة إلى " "العملية غير المقيدة؛ راجع 'man 5 apparmor.d' للحصول على التفاصيل.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "المؤهل التنفيذي '%c' غير صالح، تم تحديد المؤهل المتعارض بالفعل" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "المؤهل التنفيذي '%c%c' غير صالح، تم تحديد مؤهل متعارض بالفعل" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "داخلي: حرف وضع غير متوقع '%c' في الإدخال" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "تسبب خطأ داخلي في إنشاء إذن غير صالح 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "خطأ في محلل AppArmor: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "تعذر دمج الإدخالات. نفدت الذاكرة\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "فشل إنشاء الاسم المستعار %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "لم تعد علامة ملف التعريف 'تصحيح الأخطاء' صالحة." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "علامة ملف تعريف غير صالحة: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "تأكيد: أرجعت \"القاعدة\" قيمة خالية." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "وضع غير صالح، في قواعد الرفض يجب وضع 'x' قبل المؤهل التنفيذي 'i' أو 'p' أو " "'u'" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "وضع غير صالح، يجب وضع 'x' بعد المؤهل التنفيذي 'i' أو 'p' أو 'c' أو 'u'" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "وضع غير صالح، يجب وضع المؤهل التنفيذي 'i' أو 'p' أو 'u' قبل 'x'" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "تأكيد: أرجعت `network_rule' بروتوكولاً غير صالح." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "تأكيد: أرجع `change_profile' قيمة خالية." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "تأكيد: أرجعت \"hat rule\" قيمة خالية." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "تأكيد: أرجعت `local_profile rule' قيمة خالية." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "إلغاء تعيين المتغير المنطقي %s المستخدم في تعبير if" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "قاعدة غير آمنة بدون أذونات تنفيذ" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "لا يمكن استخدام المجموعة الفرعية إلا مع قواعد الارتباط." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "تعارض بين الارتباط والأذونات التنفيذية في قاعدة ملف عند استخدام ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" "لا يُسمح باستخدام أذونات الارتباط في عملية انتقال ملف تعريف معروفة.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "حرف نهاية سطر مفقود؟ (إدخال: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "إدخال الشبكة غير صالح." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "إمكانية غير صالحة %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: فتح غير شرعي (، غير مسموح بتجميعات متداخلة\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "%s: خطأ في تجميع Regex: عدد غير صالح للبنود بين {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: خطأ في تجميع Regex: إغلاق غير صالح }، لا يوجد فتح متوافق ( تم اكتشافه\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: خطأ في تجميع Regex: تجميع غير مغلق أو فئة أحرف غير مغلقة، الإغلاق " "المتوقع }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" "%s: تم اكتشاف تجاوز سعة الذاكرة الوسيطة الداخلية، %d تم تجاوز الأحرف\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: تعذر تحليل سطر الإدخال '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "خطأ أثناء دمج القواعد لملف التعريف %s، فشل التحميل\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "خطأ في ملف التعريف %s الذي يحتوي على عناصر سياسة غير قابلة للاستخدام مع " "kernel:\n" "\tغير مسموح باستخدام '*' و'?' ونطاقات الأحرف والتبديلات.\n" "\tلا يمكن استخدام '**' إلا في نهاية القاعدة.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "خطأ أثناء معالجة تعبيرات regex لملف التعريف %s، فشل التحميل\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "خطأ أثناء توسيع متغيرات ملف التعريف %s، فشل التحميل\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "خطأ أثناء إضافة قاعدة وصول hat لملف التعريف %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "خطأ في ملف التعريف %s، فشل التحميل\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: تم العثور على أخطاء أثناء المعالجة اللاحقة. يتم الآن الإيقاف.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" "%s: تم العثور على أخطاء أثناء المعالجة اللاحقة لـ regex. يتم الآن الإيقاف.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: تم العثور على أخطاء أثناء المعالجة اللاحقة. يتم الآن الإيقاف.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: تم العثور على أخطاء أثناء المعالجة اللاحقة لقواعد الدمج. يتم الآن " "الإيقاف.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/sv.po0000644000175000017500000006741613502024172014125 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2019-05-25 10:11+0000\n" "Last-Translator: Jonatan Nyberg \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-05-26 05:31+0000\n" "X-Generator: Launchpad (build 18968)\n" "Language: sv\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Fel: Slut på minne.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Fel: baskatalogen %s är inte en katalog. Hoppar över.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Fel: Det gick inte att lägga till katalogen %s i sökvägen.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Fel: Det gick inte att tilldela minne\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Fel skrivposition\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Åtkomst nekas\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Slut på minne\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "Gick inte att kopiera profil: Dålig minnesadress\n" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profilen följer inte protokollet\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profilen matchar inte signaturen\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Det finns inte stöd för profilversionen i AppArmor-modulen\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profilen finns redan\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profilen finns inte\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "Åtkomst nekad; försökte ladda en profil medan den är begränsad?\n" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "Okänt fel (%d): %s\n" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Det går inte att lägga till %s. " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Det går inte att ersätta %s. " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Det går inte att ta bort %s. " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Det går inte att skriva till stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "%s: Kan inte skriva till utdatafil\n" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: Felaktigt alternativ: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Tillägg lyckades för %s.\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Ersättning lyckades för %s.\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Borttagning lyckades för %s.\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "VARNING! Felaktig stegbuffert %p pos %p tillägg %p storlek %d upplösn %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "profil %s nätverksregler ej verkställda\n" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "Okänd mönstertyp\n" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Kunde inte öppna %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Minnestilldelningsfel: Det gick inte att ta bort ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Minnestilldelningsfel: Det gick inte att ta bort %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "det gick inte att skapa arbetsyta\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "det gick inte att serialisera profilen %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Det gick inte att skriva hela profilposten\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "%s: Kunde inte skriva hela profilposten till cache\n" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "Kunde inte öppna \"%s\"" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "fstat misslyckades för \"%s\"" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "opendir misslyckades '%s'" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "stat misslyckades för '%s'" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "Kunde inte öppna '%s' i '%s'" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Oväntat tecken hittades: %s" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "Variabel deklarationer tillåter inte släpande kommatecken" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "[network_mode] Ett oväntat tecken hittades: %s" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "Varning från %s (%s%sline %d): %s" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: Det gick inte att tilldela minne för underdomänbasens monteringspunkt\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Varning: Det gick inte att hitta en lämplig fs i %s. Den kanske inte har " "monterats.\n" "Åsidosätt med -subdomainfs.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Du måste ha rotbehörigheter om du vill köra det här programmet.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Varning! Du har angett det här programmet som setuid root.\n" "Alla som kan köra det här programmet kan uppdatera dina AppArmor-profiler.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Fel: Det gick inte att läsa profilen %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Minnestilldelningsfel." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "Cachad laddning lyckades för \"%s\".\n" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "Cachad återladdning lyckades för \"%s\".\n" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Fel i filen. Avbryter.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Kvalificerarna med versalerna \"RWLIMX\" har tagits bort. Ändra dem till " "gemener.\n" "Se man-sidan för apparmor.d(5) om du vill ha mer information.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" "En konflikt har uppstått. Behörigheterna a och w kan inte förekomma " "samtidigt." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Exec-kvalificeraren 'i' felaktig, kvalificerare i konflikt med denna har " "angetts" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "Med den obegränsade exec-kvalificeraren (%c%c) tillåts det att vissa farliga " "miljövariabler skickas till den obegränsade processen. Se 'man 5 apparmor.d' " "om du vill ha mer information.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Exec-kvalificeraren %c är ogiltig. En kvalificerare som står i konflikt med " "den har redan angetts" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Exec-kvalificeraren %c%c är ogiltig. En kvalificerare som står i konflikt " "med den har redan angetts." #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Internt: lägestecknet %c i indata var oväntat" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Ett internt fel genererade en ogiltig behörighet 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "AppArmor-behandlarfel: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Det gick inte att koppla posterna. Slut på minne\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "profil %s har sammanfogat regel %s med motstridiga x modifierare\n" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "profilbifogning måste börja med ett '/'." #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" "Profilnamn måste börja med ett '/', namnplats eller nyckelord 'profile' " "eller 'hat'." #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Det gick inte att skapa aliaset %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "Profilflagga chroot_relative skapar konflikt med namespace_relative" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "Profilflagga mediate_deleted skapar konflikt med delegate_deleted" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" "Profilflagga attach_disconnected skapar konflikt med no_attach_disconnected" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "Profilflagga chroot_attach skapar konflikt med chroot_no_attach" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "Profilflaggan debug är inte längre giltig." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Ogiltig profilflagga: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Förutsättning: `rule' returnerade NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Ogiltigt läge. I nekanderegler måste x föregås av någon av exec-" "kvalificerarna i, p eller u" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Ogiltigt läge. x måste föregås av någon av exec-kvalificerarna i, p, c eller " "u" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Ogiltigt läge. x måste föregås av någon av exec-kvalificerarna i, p eller u" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Förutsättning: 'network_rule_' returnerade ett ogiltigt protokoll." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Förutsättning: `change_profile' returnerade NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Förutsättning: `hat rule' returnerade NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Förutsättning: local_profile rule returnerade NULL." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" "Den booleska variabeln %s, som inte har ställts in, används i ett if-uttryck" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "osäker regel saknar exec-behörigheter" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "deluppsättning kan bara användas med länkregler." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" "link- och exec-behörigheter är i konflikt med en filregel som använder ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "link-behörigheter är inte tillåtna i en namngiven profilövergång.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "radslutstecken saknas? (post: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Ogiltig nätverkspost." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Ogiltig kapacitet %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "AppArmor tolkar fel för %s%s%s på rad %d: %s\n" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "AppArmor tolkar fel,%s%s på rad %d: %s\n" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: Otillåten inledande {, nästling av grupper tillåts inte\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "%s: Regex-grupperingsfel: Ogiltigt antal objekt inom {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Regex-grupperingsfel: Ogiltig avslutande }, ingen inledande { hittades\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Regex-grupperingsfel: Oavslutad gruppering eller teckenklass, " "avslutande } förväntas\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Internt buffertspill upptäcktes, %d tecken överskreds\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Det går inte att analysera indataraden %s\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "%s: Ogiltigt profilnamn '%s' - dåligt reguljärt uttryck\n" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" "FEL vid sammanfogning av regler för profilen %s. Det gick inte att läsa in\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "FEL: Profilen %s innehåller principelement som inte kan användas tillsammans " "med den här kerneln:\n" "\t'*', '?', teckenintervall och alterneringar är inte tillåtna.\n" "\t'**' får endast användas i slutet av en regel.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" "FEL vid behandling av reguljära uttryck för profilen %s, det gick inte att " "läsa in\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" "FEL vid expandering av variabler för profilen %s, det gick inte att läsa in\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" "Ett fel inträffade när åtkomstregeln hat skulle läggas till för profilen %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "FEL i profilen %s, det gick inte att läsa in\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: Det inträffade fel vid efterbearbetningen. Avbryter.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "%s: Fel vid efterbearbetning av regex. Avbryter.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: Det inträffade fel vid efterbearbetningen. Avbryter.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "%s: Fel i efterbearbetning av regelkombination. Avbryter.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "Det gick inte att bearbeta inkludera katalogen \"%s\" i \"%s\"" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "Funktionsbuffert full." #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "Slut på minne" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "Kan inte skapa cachekatalog: %s\n" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "Fil i cachekatalogsplats: %s\n" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "Kan inte uppdatera cachekatalog: %s\n" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "Internt: oväntat DBus-lägestecken \"%c\" i inmatning" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "Internt fel genererat ogiltigt DBus perm 0x%x\n" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "neka prefixet inte tillåtet" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "ägarprefix inte tillåtet" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "ägarprefix tillåter inte på monteraregler" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "ägarprefix tillåter inte dbus-regler" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "ägarprefix tillåter inte på kapacitetsregler" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "ogiltigt monteringsvillkorlig %s%s" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "dålig monteringsregel" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "monteringspunktsförhållanden stöds för närvarande inte" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "ogiltigt pivotroot-villkorlig \"%s\"" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" "%s: Regex-grupperingsfel: ogiltig stäng ], ingen matchning öppen [ upptäckt\n" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "%s: Regex-grupperingsfel: Överskred maximal kapsling av {}\n" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "%s: Det går inte att skriva %s\n" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "Fel: det gick inte att läsa binär profil eller cachefilen %s: %s.\n" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "Fel: Det gick inte att läsa cachefilen %s, hoppar över...\n" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "Internt: oväntat %s-lägetecken \"%c\" i inmatning" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "Internt fel genererat ogiltigt %s perm 0x%x\n" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "ägarprefix inte tillåtet på monteringsregler" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "ägarprefix inte tillåtet på dbus-regler" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "ägarprefix inte tillåtet på signalregler" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "ägarprefix inte tillåtet på ptrace-regler" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "ägarprefix inte tillåtet på unix-regler" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "ägarprefix inte tillåtet på kapacitetsregler" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "dbus-regel: ogiltig villkorlig grupp %s=()" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "unix-regel: ogiltig villkorlig grupp %s=()" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/ja.po0000644000175000017500000006555413502024172014070 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 02:52+0000\n" "Last-Translator: Novell Language \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: ja\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "エラー:メモリ不足\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "エラー:ベースディレクトリ %s はディレクトリではありません。スキップしています\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "エラー:ディレクトリ %s を検索パスに追加できませんでした。\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "エラー:メモリを割り当てることができませんでした。\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "不正書き込み位置\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "拒否されたパーミッション\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "メモリ不足\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "プロファイルがプロトコルに準拠していません\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "プロファイルが署名に一致していません\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "プロファイルバージョンがApparmorモジュールでサポートされていません\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "プロファイルはすでに存在します\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "プロファイルが存在しません\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: 「%s」を追加できません。 " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: 「%s」を置換できません。 " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: 「%s」を削除できません。 " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: stdoutに書き込めません\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT:無効なオプション: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "「%s」に続く追加。\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "「%s」に続く置換。\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "「%s」に続く削除。\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PANIC 不正増分バッファ %p pos %p ext %p size %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "開けません %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "メモリ割り当てエラー: ^%s を削除できません\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "メモリ割り当てエラー: %s:%s を削除できません。" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "作業領域を作成できません\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "プロファイル%sを順番に並べることができません\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: プロファイルエントリ全体を書き込むことができません\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "予期しない文字を検出しました: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) 予期しない文字が見つかりました:「%s」" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: サブドメインベースマウントポイントに対してメモリを割り当てることができませんでした\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "警告:適切なfsが %s に見つかりません。マウントされているか確認してください。\n" "--subdomainfsを使用して上書きしてください。\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: このプログラムを実行するには、ルート特権が必要です。\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: 警告! このプログラムのsetuidをルートに設定しました。\n" "このプログラムを実行できるユーザはすべて、AppArmorプロファイルを更新できます。\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "エラー:プロファイル %s: %s を読み込めませんでした。\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "メモリ割り当てエラー。" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: ファイルにエラーが検出されました。中止しています。\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "大文字のクォリファイア「RWLIMX」は推奨されていません。小文字に変換してください。\n" "詳細は、apparmor.d(5)のマニュアルページを参照してください。\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "競合:パーミッション「a」と「w」は互いに排他的です。" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "Execクォリファイア「i」は無効です、相反するクォリファイアがすでに指定されています" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "制限されていないexecクォリファイア(%c%c)によって、危険な環境変数が制限されていないプロセスに渡されます。詳細は、「man 5 " "apparmor.d」を参照してください。\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "Execクォリファイア「%c」は無効です。競合するクォリファイアがすで指定されています" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "Execクォリファイア'%c%c' は無効です。競合するクォリファイアがすでに指定されています" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "内部:予期しないモード文字「%c」が入力されています" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "内部エラーが発生しました。パーミッシオンが正しくありません 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "AppArmorパーサエラー: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "エントリをマージできませんでした。メモリ不足\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "別名 %s -> %s を作成することができませんでした\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "プロファイルフラグ'debug'は現在は利用できません。" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "プロファイルフラグが正しくありません: %s" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Assert:「rule」はNULLを返しています。" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "無効なモードです。拒否ルール内では「x」の前にExecクォリファイア「i」、「p」、または「u」を付けてはいけません。" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "無効なモードです。「x」の前には実行修飾子「i」、「p」、「c」または「u」が必要です。" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "無効なモードです。「x」の前にクォリファイア「i」、「p」、または「u」が必要です" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Assert:「network_rule」は無効なプロトコルを返しています。" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Assert:「change_profile」はNULLを返しています。" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Assert:「hat rule」はNULLを返しています。" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Assert: 「local_profile rule」は NULL を返しています。" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "未設定のブール値変数%sがif式に使用されています" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "ルールが安全ではありません。execパーミッションがありません" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "サブセットはリンクルールと共にのみ使用することができます" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "以下のファイルルール内でリンクとexecパーミッションが矛盾しています ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "リンクパーミッションは名前付きプロファイルの変更で使用することはできません。\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "行末文字が欠けていますか?(entry: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "無効なネットワークエントリ" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "無効な機能です %s" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: 不正オープン{、入れ子グループ分けは許可されていません\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "%s: Regexグループ分けエラー:{}の間にある項目の無効数\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "%s: Regexグループ分けエラー:無効なクローズ}、一致するオープンがありません{ detected\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "%s: Regexグループ分けエラー:グループ分けまたは文字クラスが閉じていません。クローズ}が必要です\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: 内部バッファオーバーフローが検出されました、%d文字超えています\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: 入力行「%s」を解析できません\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "プロファイル %s のルールをマージ中にエラーが発生しました。ロードできませんでした\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "エラー:プロファイル %s にこのカーネルで使用できないポリシー要素があります:\n" "\t「*」、「?」、文字範囲、交代は許可されません。\n" "\t「**」はルールの末尾にのみ使用できます。\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "プロファイル %s のregex処理中にエラーが発生しました。ロードできませんでした\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "プロファイル %s の変数の拡張中にエラーが発生しました。ロードできませんでした\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "プロファイル %s にハットアクセスルールを追加する際にエラーになりました\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "プロファイル%sのエラー、ロードに失敗しました\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: 後処理の際にエラーが発生しました。中止しています。\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "%s: regex後処理の間にエラーが見つかりました。中止しています。\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: 後処理の際にエラーが発生しました。中止しています。\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "%s: 規則後処理の結合中にエラーが見つかりました。中断しています。\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/bn.po0000644000175000017500000005735113502024172014071 0ustar jjjjmsgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 01:37+0000\n" "Last-Translator: Priyavert \n" "Language-Team: AgreeYa Solutions \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: bn\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "লেখার খারাপ অবস্থান\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "অনুমতি অস্বীকার করা হয়েছে\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "স্মৃতি পরিপূর্ণ\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "প্রোফাইল প্রোটোকল মেনে চলে না\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "প্রোফাইল স্বাক্ষরের সাথে মেলে না\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "প্রোফাইল ইতোমধ্যেই বিদ্যমান\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "প্রোফাইলের অস্তিত্ব নেই\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: \"%s\" যোগ করতে পারে নি। " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: \"%s\" প্রতিস্থাপন করতে পারে নি। " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: \"%s\" অপসারণ করতে পারে নি। " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: stdout এ লিখতে অক্ষম\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: অবৈধ বিকল্প: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "\"%s\" এর ক্ষেত্রে যোগ করা সফল হয়েছে।\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "\"%s\" এর ক্ষেত্রে প্রতিস্থাপন সফল হয়েছে।\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "\"%s\"এর ক্ষেত্রে অপসারণ সফল হয়েছে।\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PANIC খারাপ ইনক্রিমেন্ট বাফার %p pos %p ext %p size %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "%s খুলতে পারে নি - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "কাজের এলাকা তৈরি করতে পারে নি\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "%s প্রোফাইল ক্রমিক করতে পারে নি\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: সমগ্র প্রোফাইল এনট্রি লিখতে অক্ষম\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "অপ্রত্যাশিত অক্ষর পাওয়া গেছে: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: সাবডোমেনবেস মাউন্ট পয়েন্টের জন্যে স্মৃতি বন্টন করতে পারে নি\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "স্মৃতি বন্টনে ত্রুটি।" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: ফাইলে ত্রুটি পাওয়া গেছে। বাতিল করছে।\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "Exec কোয়ালিফায়ার 'i' অবৈধ, বিবাদমান কোয়ালিফায়ার ইতোমধ্যেই বিদ্যমান" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "এনট্রিগুলি একীভূত করতে পারে নি।স্মৃতি পরিপূর্ণ\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "দৃঢ় ঘোষণা: `rule' NULL ফেরত পাঠিয়েছে।" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "দৃঢ় ঘোষণা: `hat rule' NULL ফেরত পাঠিয়েছে।" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "লাইন সমাপ্তির অক্ষর অনুপস্থিত? (এনট্রি: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: অবৈধ খোলা {, নেস্টিং গ্রুপিংয়ের অনুমতি নেই\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "%s: Regex দলবদ্ধকরণের ত্রুটি: {} এর মধ্যে অবৈধ সংখ্যক বস্তু\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Regex দলবদ্ধকরণের ত্রুটি: অবৈধ বন্ধ }, কোন মিলযুক্ত খোলা{ পাওয়া যায় নি\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" "%s: অভ্যন্তরীণ বাফার অতিপ্রবাহের সন্ধান পাওয়া গেছে, %d গুলি অক্ষর বেশি\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: ইনপুট ফাইল '%s' পার্স করতে অক্ষম\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "%s প্রোফাইলে ত্রুটি আছে, চালাতে ব্যর্থ হয়েছে\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: পোস্টপ্রসেসিং নিয়মাবলী একীভূত করায় ত্রুটি পাওয়া গেছে। বাতিল করছে।\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/lt.po0000644000175000017500000005301713502024172014104 0ustar jjjj# translation of apparmor-parser.po to Lietuvių # Copyright (C) 2005 SUSE Linux Products GmbH. # Copyright (C) 2002 SuSE Linux AG. # Copyright (C) 2000, 2001 SuSE GmbH. # Jonas Gocentas , 2001. # Linas Spraunius , 2000. # Andrius Štikonas , 2006. msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 03:03+0000\n" "Last-Translator: Andrius Štikonas \n" "Language-Team: Lietuvių \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: lt\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Klaida: nepakanka atminties.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Klaida: nepavyksta pridėti aplanko %s į paieškos kelią.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Klaida: nepavyksta paskirstyti atminies.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Bloga rašymo pozicija\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Priėjimas uždraustas\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Nepakanka atminties\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profilis neatitinka parašo\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Apparmor modulis nepalaiko profilio versijos\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profilis jau egzistuoja\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profilis neegzistuoja\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Nepavyksta pridėti \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Nepavyksta pakeisti \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Nepavyksta pašalinti \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Nepavyksta rašyti į stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Nepavyksta atverti %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Rastas netikėtas simbolis: „%s“" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Apgailestaujame. Kad paleistumėte šią programą, jums reikia root " "privilegijų.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Klaida: nepavyksta nuskaityti profilio %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Atminties išskyrimo klaida." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Faile rasta klaidų. Nutraukiama.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Nepavyksta apjungti įrašų. Nepakanka atminties\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: nepavyksta išnagrinėti įvesties eilutės „%s“\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "KLAIDA profilyje %s, nepavyko įkelti\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/ko.po0000644000175000017500000006457113502024172014105 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-20 22:27+0000\n" "Last-Translator: Litty \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: ko\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "오류: 메모리가 부족합니다.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "오류: basedir %s은(는) 디렉토리가 아니므로 건너뜁니다.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "오류: %s 디렉토리를 검색 경로에 추가할 수 없습니다.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "오류: 메모리를 할당할 수 없습니다.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "쓰기 위치가 잘못되었습니다.\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "사용 권한이 거부되었습니다.\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "메모리 부족\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "프로필을 복사할 수 없습니다: 잘못된 메모리 주소\n" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "프로파일이 프로토콜과 맞지 않습니다.\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "프로필과 서명이 일치하지 않음\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "프로파일 버전이 Apparmor 모듈에서 지원되지 않습니다.\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "프로파일이 이미 있습니다.\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "프로파일이 없습니다.\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: \"%s\"을(를) 추가할 수 없습니다. " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: \"%s\"을(를) 바꿀 수 없습니다. " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: \"%s\"을(를) 제거할 수 없습니다. " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: stdout에 쓸 수 없습니다.\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: 잘못된 옵션: - %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "\"%s\"에 성공적으로 추가했습니다.\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "\"%s\"의 바꾸기 작업이 성공했습니다.\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "\"%s\"의 제거 작업이 성공했습니다.\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PANIC 잘못된 증분 버퍼 %p 위치 %p 확장 %p 크기 %d 결과 %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "%s을(를) 열 수 없음 - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "메모리 할당 오류: ^%s을(를) 제거할 수 없습니다.\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "메모리 할당 오류: %s:%s을(를) 제거할 수 없습니다." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "작업 영역을 생성할 수 없습니다.\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "프로파일 %s을(를) 일련번호화할 수 없습니다.\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: 전체 프로파일 항목에 쓸 수 없습니다.\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "잘못된 문자가 있음: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) 잘못된 문자가 있음: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: 서브도메인베이스 마운트 포인트에 대해 메모리를 할당할 수 없습니다.\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "경고: %s에 적합한 fs가 없습니다. 마운트되어 있습니까?\n" "--subdomainfs를 사용하여 무시할 수 있습니다.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: 이 프로그램을 실행하려면 루트 권한이 필요합니다.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: 경고! 이 프로그램을 setuid 루트로 설정했습니다.\n" "따라서 이 프로그램을 실행할 수 있는 모든 사용자가 AppArmor 프로파일을 업데이트할 수 있습니다.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "오류: 프로파일 %s을(를) 읽을 수 없음: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "메모리 할당 오류입니다." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: 파일에 오류가 발견되어 중단합니다.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "대문자 한정자 \"RWLIMX\"는 더 이상 사용되지 않습니다. 소문자로 변경하십시오.\n" "자세한 내용은 apparmor.d(5) 맨페이지를 참조하십시오.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "'a' 및 'w' 사용권한을 동시에 설정할 수 없습니다." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "실행 한정자 'i'는 충돌을 일으켜 사용할 수 없습니다. 같은 한정자가 이미 지정되어 있습니다." #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "제한되지 않은 실행 한정자(%c%c)를 사용하면 위험한 환경 변수가 제한되지 않은 프로세스로 전달될 수 있습니다. 자세한 내용은 'man " "5 apparmor.d'를 참조하십시오.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "실행 한정자 '%c'은(는) 충돌을 일으키므로 사용할 수 없습니다. 같은 한정자가 이미 지정되어 있습니다." #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "실행 수식자 '%c%c'이(가) 잘못되었습니다. 이미 지정된 수식자와 충돌합니다." #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "내부 오류: 잘못된 모드 문자 '%c'이(가) 입력되었습니다." #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "내부 오류 발생. 잘못된 권한 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "AppArmor 구문 분석 오류: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "항목을 병합할 수 없습니다. 메모리가 부족합니다.\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "별칭 %s을(를) 만들지 못했습니다. -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "'debug' 프로파일 플래그가 더 이상 유효하지 않습니다." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "잘못된 프로파일 플래그: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "어설션: `rule'이 NULL을 반환했습니다." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "잘못된 모드. 거부 규칙에서 'x' 앞에 실행 수식자 'i', 'p' 또는 'u'가 선행되어서는 안됩니다." #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "잘못된 모드. 'x' 앞에 실행 수식자 'i', 'p', 'c' 또는 'u'가 선행되어야 합니다." #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "잘못된 모드입니다. 'x'는 실행 한정자 'i', 'p' 또는 'u' 뒤에 와야 합니다." #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "어설션: `network_rule'이 잘못된 프로토콜을 반환합니다." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "어설션: `change_profile'이 NULL을 반환했습니다." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "어설션: 'hat rule'이 NULL을 반환했습니다." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "평가: 'local_profile rule'이 NULL을 반환했습니다." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "if 식에 사용된 부울 변수 %s의 설정이 해제되었습니다." #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "실행 권한이 누락되어 규칙이 안전하지 않습니다." #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "하위 집합은 링크 규칙에만 사용할 수 있습니다." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "다음을 사용하는 파일 규칙에서 링크 및 실행 권한 충돌 ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "링크 권한이 명명된 프로파일 전환에서 허용되지 않습니다.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "행의 끝 문자가 누락되었습니까? (항목: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "잘못된 네트워크 항목입니다." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "성능 %s이(가) 잘못되었습니다." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: 여는 괄호 {가 잘못되었습니다. 중첩 그룹은 허용되지 않습니다.\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "%s: 정규식 그룹화 오류: {} 사이의 항목 수가 잘못됨\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "%s: 정규식 그룹화 오류: 닫는 괄호 }에 해당하는 여는 괄호 {가 없습니다.\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "%s: 정규식 그룹화 오류: 닫히지 않은 그룹화 또는 문자 클래스가 있습니다. 닫는 괄호 }가 필요합니다.\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: 내부 버퍼 오버플로 탐지, %d자가 초과되었습니다.\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: 입력 행 '%s'의 구문을 분석할 수 없습니다.\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "%s 프로파일의 규칙을 병합하는 중에 오류가 발생하여 로드하지 못했습니다.\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "오류: %s 프로파일은 이 커널로 사용할 수 없는 정책을 포함합니다:\n" "\t'*', '?', 문자 범위 및 변경은 허용되지 않습니다.\n" "\t'**'는 규칙의 마지막 부분에만 사용할 수 있습니다.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "%s 프로파일의 정규식을 처리하는 중에 오류가 발생하여 로드하지 못했습니다.\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "%s 프로파일의 변수를 확장하는 중에 오류가 발생하여 로드하지 못했습니다.\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "프로파일에 대한 hat 액세스 규칙 추가 중 오류 %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "프로파일 %s에 오류가 발생하여 로드하지 못했습니다.\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: 후처리 도중 오류가 발견되었습니다. 중단 중입니다.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "%s: 정규식 후처리 시 오류가 발생했습니다. 프로세스를 중단합니다.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: 후처리 도중 오류가 발견되었습니다. 중단 중입니다.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "%s: 규칙 후처리를 결합하는 중에 오류가 발생했습니다. 프로세스를 중단합니다.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/el.po0000644000175000017500000006354313502024172014072 0ustar jjjj# translation of apparmor-parser.el.po to Ελληνικά # @TITLE@ # Copyright (C) 2006, SUSE Linux GmbH, Nuremberg # # This file is distributed under the same license as @PACKAGE@ package. FIRST # # Vasileios Giannakopoulos , 2007. # Kostas Boukouvalas , 2007. # Vasileios Giannakopoulos , 2008. msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 01:42+0000\n" "Last-Translator: Vasileios Giannakopoulos \n" "Language-Team: Ελληνικά \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: el\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Σφάλμα: Μνήμη πλήρης.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Σφάλμα: Το basedir %s δεν είναι κατάλογος, παραβλέπεται.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Σφάλμα: Αδυναμία προσθήκης καταλόγου %s στη διαδρομή έρευνας.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Σφάλμα: Αδυναμία προσδιορισμού μνήμης.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Λάθος θέση εγγραφής\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Απαγορεύεται η πρόσβαση\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Μνήμη πλήρης\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Το προφίλ δεν εναρμονίζεται με το πρωτόκολλο\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Το προφίλ δεν ταιράζει με την υπογραφή\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Η έκδοση προφίλ δεν υποστηρίζεται από την μονάδα Apparmor\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Το προφίλ υπάρχει ήδη\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Το προφίλ δεν υπάρχει\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Αδυναμία προσθήκης \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Αδυναμία αντικατάστασης \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s Αδυναμία αφαίρεσης \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Αδυναμία εγγραφής στο stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s ΠΑΡΕΜΒΑΣΗ: Λανθασμένη επιλογή: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Η προσθήκη υπερβαίνει για \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Η αντικατάσταση υπερβαίνει για \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Removal succeeded for \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PANIC κακή ζώνη ποσοτήτων %p pos %p ext %p size %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Αδυναμία ανοίγματος %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "αδυναμία δημιουργίας χώρου εργασίας\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "αδυναμία σειριοποίησης προφίλ %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Αδυναμία εγγραφής ολόκληρου του προφίλ\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Βρέθηκε μη αναμενόμενος χαρακτήρας: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: Αδυναμία προσδιορισμού μνήμης για subdomainbase σημείο προσάρτησης\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Συγγνώμη. Δεν έχετε δικαιώματα υπερχρήστη για να τρέξετε αυτό το " "πρόγραμμα.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Προειδοποίηση! Έχετε ορίσει αυτό το πρόγραμμα setuid root.\n" "Οποιοσδήποτε μπορεί να τρέξει αυτό το πρόγραμμα, μπορεί να ενημερώσει τα " "προφίλ AppArmor.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Σφάλμα: Αδυναμία ανάγνωσης profile %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Σφάλμα προσδιορισμού μνήμης." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Βρέθηκαν σφάλματα στο αρχείο. Αποχώρηση.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Κεφαλαίοι χαρακτήρες \"RWLIMX\" αποφεύγονται, παρακαλώ αλλάξτε σε μικρά\n" "Δείτε το apparmor.d(5) για λεπτομέρειες.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "Χαρακτήρας exec 'i' λάθος, συμπλέκεται με ήδη υπάρχων χαρακτήρα" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Χαρακτήρας exc '%c' λανθασμένος, συμπλέκεται με ήδη καθορισμένο χαρακτήρα" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Εσωτερικό: μη αναμενόμενη λειτουργία χαρακτήρα '%c' στην είσοδο" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "Σφάλμα αναλυτή AppArmor: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Αδυναμία συγχώνευσης εγγραφών. Μνήμη Πλήρης\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Παρέμβαση: 'rule' επέστρεψε ΜΗΔΕΝ." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Σφάλμα λειτουργίας, το 'x' θα πρέπει να προηγείται του χαρακτήρα exec 'i', " "'p' ή 'u'" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Παρέμβαση: 'hat rule' επέστρεψε ΜΗΔΕΝ." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Η μη ορισμένη μεταβλητή boolean %s χρησιμοποιήθηκε στην if-έκφραση" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "λείπει ένα τέλος στη γραμή χαρακτήρα; (εγγραφή: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: Παράνομο άνοιγμα {, δεν επιτρέπονται ομαδοποιήσεις\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: Σφάλμα ομαδοποίησης Regex: Λάθος αριθμός αντικειμένων μεταξύ {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Σφάλμα ομαδοποίησης Regex: Λάθος κλείσιμο }, δεν βρέθηκε ταιριαστό " "άνοιγμα {\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Σφάλμα ομαδοποίησης Regex: Ανοιχτή ομαδοποίηση ή κλάσση χαρακτήρα, " "αναμένεται κλείσιμο }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Εσωτερική διαρροή ζώνης ανιχνεύθηκε, υπέρβαση %d χαρακτήρων\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Αδυναμία ανάλυσης γραμμής εισόδου '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "ΣΦΑΛΜΑ συγχώνευσης κανόνων για το προφίλ %s, αδυναμία φόρτωσης\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "ΣΦΑΛΜΑ προφίλ %s περιέχει αντικείμενα πολιτικής που δε χρησιμοποιούνται από " "αυτόν τον πυρήνα:\n" "\t'*', '?', πεδία χαρακτήρων και αλλαγές δεν επιτρέπονται.\n" "\t'**' μπορεί να χρησιμοποιηθεί μόνο στο τέλος.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "ΣΦΑΛΜΑ επεξεργασίας regexs για το προφίλ %s, αδυναμία φόρτωσης\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "ΣΦΑΛΜΑ επέκτασης μεταβλητών για προφίλ %s, αδυναμία φόρτωσης\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "ΣΦΑΛΜΑ το προφίλ %s, αδυναμία φόρτωσης\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" "%s: Βρέθηκαν σφάλματα κατα τη διάρκεια της μετεπεξεργασίας regex. " "Αποχώρηση.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Βρέθηκαν σφάλματα στους συνδυαστικούς κανόνες μετεπεξεργασίας. " "Αποχώρηση.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/apparmor-parser.pot0000644000175000017500000005064313502024172016766 0ustar jjjj# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR NOVELL, Inc. # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/pt_BR.po0000644000175000017500000006273213502024172014477 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 03:51+0000\n" "Last-Translator: Novell Language \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: pt_BR\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Erro: Sem memória.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Erro: O diretório base %s não é um diretório; ignorando.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" "Erro: Não foi possível adicionar o diretório %s ao caminho de pesquisa.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Erro: Não foi possível alocar memória.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Posição de gravação incorreta\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Permissão negada\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Memória insuficiente\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Perfil não compatível com o protocolo\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Perfil não corresponde à assinatura\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Versão de perfil não suportada pelo módulo do AppArmor\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "O perfil já existe\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "O perfil não existe\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Impossível adicionar \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Impossível substituir \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Impossível remover \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Impossível gravar em stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: DECLARAR: Opção inválida: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Adição bem-sucedida de \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Substituição bem-sucedida de \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Remoção bem-sucedida de \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "PÂNICO: buffer de incremento incorreto %p pos %p ext %p tamanho %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Impossível abrir %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Erro de Alocação de Memória: Impossível remover ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Erro de Alocação de Memória: Impossível remover %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "impossível criar área de trabalho\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "impossível serializar perfil %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Impossível gravar toda a entrada do perfil\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Caractere inesperado encontrado: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) Caractere inesperado encontrado: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: Impossível alocar memória para ponto de montagem de base de subdomínio\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Aviso: impossível encontrar um fs adequado em %s. Ele está montado?\n" "Use --subdomainfs para anular.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Você precisa de privilégios de root para executar este programa.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Aviso! Você definiu o setuid deste programa como root.\n" "Qualquer pessoa capaz de executar esse programa poderá atualizar seus perfis " "do AppArmor.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Erro: Não foi possível ler o perfil %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Erro de alocação de memória." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Erros encontrados no arquivo. Interrompendo.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Os qualificadores maiúsculos \"RWLIMX\" foram cancelados; converta-os em " "letras minúsculas\n" "Consulte a página de manual apparmor.d(5) para obter detalhes.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "As permissões 'a' e 'w' de conflito são mutuamente exclusivas." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Qualificador de execução 'i' inválido. Qualificador em conflito já " "especificado" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "O qualificador de execução não delimitado (%c%c) permite que algumas " "variáveis de ambiente perigosas sejam passadas para o processo não " "delimitado; consulte 'man 5 apparmor.d' para obter detalhes.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Qualificador de execução '%c' inválido. Qualificador em conflito já " "especificado" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Qualificador de execução '%c%c' inválido. Qualificador em conflito já " "especificado" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Interno: caractere '%c' inesperado de modo na entrada" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Erro interno gerou permissão inválida 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "Erro do analisador do AppArmor: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Impossível mesclar entradas. Memória Insuficiente\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Falha ao criar o álias %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "O flag de perfil 'debug' não é mais válido." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Flag de perfil inválido: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Declarar: `rule' retornou NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Modo inválido. Nas regras de negação, o 'x' não deve ser precedido pelo " "qualificador de execução 'i', 'p' ou 'u'" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Modo inválido. O 'x' deve ser precedido pelo qualificador de execução 'i', " "'p','c' ou 'u'" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Modo inválido; 'x' deve ser precedido pelo qualificador de execução 'i', 'p' " "ou 'u'" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Declarar: `network_rule' retornou um protocolo inválido." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Declarar: `change_profile' retornou NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Declarar: 'hat rule' retornou NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Declaração: a regra 'local_profile' retornou NULO." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Cancelar a definição da variável booleana %s usada na expressão if" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "permissões de execução não seguras com regra ausente" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "subconjunto somente deve ser usado com regras de link." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" "conflito de permissões de link e execução em uma regra de arquivo usando ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" "permissões de link não são permitidas em uma transição de perfil nomeada.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "caractere de fim de linha ausente? (entrada: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Entrada de rede inválida." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Recurso inválido %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: Abertura ilegal {, agrupamentos aninhados não permitidos\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: Erro de agrupamento de expressão regular: Número inválido de itens entre " "{}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Erro de agrupamento de expressão regular: Fechamento inválido }; nenhuma " "abertura correspondente { detectada\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Erro de agrupamento de expressão regular: Classe de caractere ou " "agrupamento não fechado; aguardando fechamento }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Overflow de buffer interno detectado; %d caracteres excedidos\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Impossível analisar linha de entrada '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "ERRO ao fundir regras para o perfil %s; falha ao carregar\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "ERRO: O perfil %s contém elementos de política que não podem ser usados com " "este kernel:\n" "\t'*', '?', faixas de caracteres e alternações não são permitidos.\n" "\t'**' somente podem ser usados no final de uma regra.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" "ERRO no processamento de expressões regulares para o perfil %s; falha ao " "carregar\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "ERRO ao expandir variáveis para o perfil %s; falha ao carregar\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "ERRO ao adicionar a regra de acesso hat para o perfil %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "ERRO no perfil %s. Falha ao carregar\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: erros encontrados durante o pós-processamento. Interrompendo.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" "%s: Erros encontrados durante o pós-processamento de expressão regular. " "Interrompendo.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: erros encontrados durante o pós-processamento. Interrompendo.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Erros encontrados no pós-processamento de regras de combinação. " "Interrompendo.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/pt.po0000644000175000017500000006473213502024172014116 0ustar jjjj# translation of apparmor-parser.pt.po to Portuguese # English translations for subdomain_parser package. # Copyright (C) 2005 Immunix, Inc. # This file is distributed under the same license as the subdomain_parser package. # # Steve Beattie , 2005. # Antonio Cardoso Martins , 2006, 2007, 2008. # Carlos Gonçalves , 2007. msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2016-03-03 08:40+0000\n" "Last-Translator: Ivo Xavier \n" "Language-Team: Portuguese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: pt\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Erro: Memória Esgotada.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Erro: basedir %s não é um directório, a saltar.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" "Erro: Não é possível adicionar o directório %s ao caminho de procura.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Erro: Não é possível alocar memória.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Posição de escrita errada\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Permissão negada\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Memória esgotada\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "Não pode copiar o perfil: Mau endereço de memória\n" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "O perfil não está em conformidade com o protocolo\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "O perfil não coincide com a assinatura\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Versão de perfil não suportada pelo módulo Apparmor\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "O perfil já existe\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "O perfil não existe\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "Permissão negada; tentar carregar um perfil enquando confinado?\n" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "Erro desconhecido (%d): %s\n" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Não é possível adicionar \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Não é possível substituir \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Não é possível remover \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Não é possível escrever em stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "%s: Incapaz de escrever no ficheiro de saída\n" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERÇÃO: Opção inválida: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Adição bem sucedida para \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Substituição bem sucedida para \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Remoção bem sucedida para \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "PÂNICO buffer de incremento errado %p pos %p ext %p tamanho %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "regras de perfil %s na rede não impostas\n" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "Tipo de padrão desconhecido\n" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Não é possível abrir %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Erro de Alocação de Memória. Não é possível remover ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Erro de Alocação de Memória. Não é possível remover %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "não é possível criar área de trabalho\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "não é possível serializar o perfil %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Não é possível escrever a entrada completa de perfil\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "%s: Incapaz de escrever a entrada inteira de perfil na cache\n" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "Não foi possível abrir '%s'" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "fstat falhou para '%s'" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "opendir falhou '%s'" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "stat falhou para '%s'" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "Não pode abrir '%s' em '%s'" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Encontrado caracter inesperado: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) Encontrado caracter inesperado: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "Avisos de %s (%s%sline %d): %s" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: Não é possível alocar memória para o ponto de montagem de subdomainbase\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Aviso: não é possível encontrar um fs adequado em %s, estará ele montado?\n" "Utilize --subdomainfs para sobrepor.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Lamento. Necessita de privilégios de root para executar este programa.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Aviso! Definiu este programa como setuid root.\n" "Qualquer utilizador que possa executar este programa pode actualizar os seus " "perfis AppArmor.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Erro: Não é possível ler o perfil %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Erro de alocação de memória." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Foram encontrados erros no ficheiro. A interromper.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Os qualificadores maiúsculos \"RWLIMX\" estão obsoletos, por isso converta-" "os para minúsculas\n" "Para mais detalhes consulte a página de manual do apparmor.d(5).\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "As permissões 'a' e 'w' em conflito são mutuamente exclusivas." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Qualificador de execução 'i' inválido, qualificador em conflito já " "especificado" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "O qualificador de execução não constrangido (%c%c) permite a passagem de " "variáveis de ambiente perigosas para o processo não confinado; digite 'man 5 " "apparmor.d' para mais detalhes.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Qualificador de execução '%c' inválido, qualificador em conflito já " "especificado" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Qualificador de execução '%c%c' inválido, qualificador em conflito já " "especificado" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Interno: entrada com caracter de modo '%c' inesperado" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Erro interno gerou permissão inválida 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "Erro de interpretação AppArmor: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Não é possível intercalar as entradas. Memória Esgotada\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "Anexo de perfil deve começar com '/'." #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Falha na criação da alcunha %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "A marca 'debug' de perfil já não é válida." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Marca de perfil inválida: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Asserção: `rule' devolveu NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Modo inválido, em regras de negação, o 'x' deve ser precedido por um " "qualificador de execução 'i', 'p' ou 'u'" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Modo inválido, 'x' deve ser precedido por um qualificador de execução 'i', " "'p', 'c' ou 'u'" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Modo inválido, 'x' deve ser precedido por um qualificador de execução 'i', " "'p' ou 'u'" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Asserção: `network_rule' ' devolveu protocolo inválido." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Asserção: `change_profile' devolveu NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Asserção: 'hat rule' devolveu NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Asserção: `local_profile rule' devolveu NULL." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Variável booleana %s não definida em expressão condicional" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "Regra insegura por falta de permissões de execução" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "subconjunto pode apenas ser utilizado com regras de ligação." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" "permissões de link e exec conflictuam numa regra de ficheiro utilizando ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" "permissões de link não são permitidas numa transição de perfil nomeada.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "caracter de fim de linha em falta? (entrada: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Entrada de rede inválido." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Capacidade inválida %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" "%s: { de abertura ilegal, o encadeamento de agrupamentos não é permitido\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: Erro de agrupamento de expressões regulares: Número inválido de itens " "entre {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Erro de agrupamento de expressões regulares: Fecho inválido }, não foi " "encontrado uma } para emparelhar\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Erro de agrupamento de expressões regulares: Agrupamento ou classe de " "caracter não encerrado, espera-se uma } a fechar\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Detectado um excesso no buffer interno de %d caracteres\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Não foi possível analisar a linha de entrada '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "ERRO falhou a carga das regras de fusão do perfil %s\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "ERRO perfil %s contém elementos de política não utilizáveis com este " "kernel:\n" "\t'*', '?', gamas de caracteres e alternações não são permitidos.\t'**' pode " "apenas ser utilizado no fim de uma regra.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "ERRO ao processar regexs para o perfil '%s', falhou a carga\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "ERRO ao expandir as variáveis para o perfil '%s', falhou a carga\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "ERRO ao adicionar a regra de acesso 'hat' para o perfil %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "ERRO no perfil %s, falhou o carregamento\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" "%s: Foram encontrados erros durante o pós-processamento. A interromper.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" "%s: Foram encontrados erros durante o pós-processamento das expressões " "regulares (regex). A interromper.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" "%s: Foram encontrados erros durante o pós-processamento. A interromper.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Foram encontrados erros no pós-processamento de combinação de regras. A " "interromper.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "Sem memória" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "Não foi possível criar diretório de cache: %s\n" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "Não foi possível atualizar o diretório da cache: %s\n" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/tr.po0000644000175000017500000005727113502024172014120 0ustar jjjj# Turkish message file for YaST2 (@memory@). # Copyright (C) 2005 SUSE Linux Products GmbH. # Copyright (C) 2002 SuSE Linux AG. # Copyright (C) 1999, 2000, 2001 SuSE GmbH. # Görkem Çetin , 1999, 2000. # Mehmet Mıdık , 2000. # Metin Oral , 2001. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 03:41+0000\n" "Last-Translator: Ömer Kehri \n" "Language-Team: turkish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: tr\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Hata: Yetersiz bellek.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Hata: %s temel dizini bir dizin değil, atlanıyor.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Hata: %s dizini arama yollarına eklenemedi.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Hata: Bellek tahsis edilemedi.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Hatalı yazma pozisyonu\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "İzin verilmedi\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Yetersiz bellek\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profil protokole uymuyor\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profil imzası tutmuyor\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Profil sürümü Apparmor modülü tarafından desteklenmiyor\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profil zaten mevcut\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profil mevcut değil\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: \"%s\" eklenemedi. " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: \"%s\" değiştirilemedi. " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: \"%s\" silinemedi. " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: stdout'a yazılamadı.\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: Geçersiz seçenek: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "\"%s\" için ekleme başarılı oldu.\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "\"%s\" için değiştirme başarılı oldu.\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "\"%s\" için silme başarılı oldu.\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "PANİK hatalı arttırma arabelleği %p pozisyon %p ext %p boyut %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "%s açılamadı - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "çalışma alanı oluşturulamadı\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "%s profili seri hale getirilemedi\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Profil girdisinin tamamı yazılamadı\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Beklenmeyen karakter bulundu: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: subdomainbase bağlantı noktası için bellek ayrılamadı\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Bu programı çalıştırabilmek için root yetkilerine ihtiyacınız var.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Uyarı! Bu programın setuid değeri root olarak ayarlanmış.\n" "Bu programı çalıştıracak herkes AppArmor profillerinizi değiştirebilir.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Hata: %s profili okunamadı: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Bellek ayırma hatası." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Dosyada hatalar bulundu. Durduruluyor.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Büyük harfli niteleyiciler \"RWLIMX\" yakında eskiyecektir, bunları küçük " "harfe çevirin\n" "Ayrıntılar için apparmor.d(5) manual sayfasına bakın.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Çalıştırma niteleyicisi 'i' geçersiz, çakışan niteleyici zaten belirtilmiş" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Çalıştırma niteleyicisi '%c' geçersiz, çakışan niteleyici zaten belirtilmiş" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Dahili: girdide beklenmeyen mod karakteri '%c'" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "AppArmor inceleyici hatası: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Girdiler birleştirilemiyor. Yetersiz bellek\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Assert: `rule' NULL döndürdü." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Geçersiz mod; 'x', çalıştırma değişkenleri 'i', 'p' ya da 'u'dan sonra " "gelmelidir." #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Assert: `hat rule' NULL döndürdü." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "If deyimi içinde ayarlanmamış boolean değişkeni %s" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "eksik satır sonu karakteri? (girdi: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: Kural dışı açık {, iç içe konan gruplamalara izin verilmez\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "%s: Regex gruplama hatası: {} içinde geçersiz öğe sayısı\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Regex gruplama hatası: Geçersiz kapama }, karşılığı olan bir { " "bulunamadı\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Regex gruplama hatası: Kapatılmamış gruplama ya da karakter sınıfı, " "kapama karakteri } bekleniyor\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Dahili ara bellek taşması saptandı, %d karakter aşıldı\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Giriş satırı '%s' incelenemedi\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" "HATA: %s profilinin kuralları birleştirilemedi, yükleme başarısız oldu\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "HATA: %s profili bu kernel ile kullanılamayacak bazı ilke öğeleri içeriyor:\n" "\t'*', '?', karakter aralıkları ve sırayla birbirini izlemelere izin " "verilmiyor.\n" "\t'**' sadece bir kuralın sonunda kullanılabilir.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "HATA: %s profilinin regex'leri işlenemedi, yükleme başarısız oldu\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" "HATA: %s profili için değişkenler genişletilemedi, yükleme başarısız oldu\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "HATA: %s profili, yükleme başarısız oldu\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "%s: Regex sonrası işlemlerde hata bulundu. Durduruluyor.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Kural birleştirme sonrası işlemlerde hata bulundu. Durduruluyor.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/km.po0000644000175000017500000007760513502024172014105 0ustar jjjj# translation of apparmor-parser.km.po to Khmer # Khoem Sokhem , 2006, 2007, 2008. # Auk Piseth , 2006, 2007. # translation of apparmor-parser.km.po to msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 02:34+0000\n" "Last-Translator: Khoem Sokhem \n" "Language-Team: Khmer \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: km\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "កំហុស ៖ អស់​សតិ ។\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "កំហុស  ៖ basedir %s មិនមែន​ថត​ឡើយ​ កំពុង​រំលង ។\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "កំហុស​ ៖ មិន​អាច​បន្ថែម​ថត​ %s ដើម្បី​ស្វែងរក​ផ្លូវ​បាន​ឡើយ​ ។\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "កំហុស​ ៖ មិន​អាច​បម្រុង​សតិ​ទុក​​ ។\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "ទីតាំង​សរសេរ​ខូច\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "សិទ្ធិ​ត្រូវ​បាន​បដិសេធ\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "អស់​សតិ\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "ទម្រង់​មិន​អះអាង​ទៅ​ពិធីការ\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "ទម្រង់​មិន​ផ្គូផ្គង​ហត្ថលេខា\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "ទម្រង់កំណែ​​មិន​ត្រូវ​បាន​គាំទ្រ​ដោ​យ​ម៉ូឌុល​ Apparmor ឡើយ\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "ទម្រង់​មាន​រួច​ហើយ\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "មិន​មាន​ទម្រង់​ឡើយ\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s ៖ មិន​អាច​បន្ថែម \"%s\" ។ " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s ៖ មិន​អាច​ជំនួស \"%s\" ។ " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s ៖ មិន​អាច​យក \"%s\" ចេញ ។ " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s ៖ មិន​អាច​សរសេរ​ទៅ stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s ៖ ASSERT ៖ ជម្រើស​មិន​ត្រឹមត្រូវ ៖ %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "ការ​បន្ថែម​បាន​ជោគជ័យ​សម្រាប់ \"%s\" ។\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "ការ​ជំនួស​បាន​ជោគជ័យ​សម្រាប់ \"%s\" ។\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "ការ​យក​ចេញ​បាន​ជោគជ័យ​សម្រាប់ \"%s\" ។\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "មិន​អាច​បើក %s - %s បានឡើយ\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "កំហុស​ក្នុង​កា​របម្រុងទុក​សតិ ៖ មិន​អាច​យក ^%s ចេញ\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "កំហុស​ក្នុង​កា​របម្រុង​ទុក​សតិ ៖ មិន​អាច​យក %s:%s ។" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "មិន​អាច​បង្កើត​តំបន់​ធ្វើការ\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "មិន​អាច​កំណត់​ទម្រង់ %s ជា​ស៊េរី​បាន​ឡើយ\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s ៖ មិន​អាច​សរសេរធាតុ​ទម្រង់​ទាំង​មូល\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "រក​ឃើញ​តួអក្សរ​ដែល​មិន​រំពឹង ៖ '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) រក​ឃើញ​តួអក្សរ​ដែល​មិន​រំពឹង​ទុក ៖ '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s ៖ មិន​អាច​បម្រុង​ទុក​សតិ​សម្រាប់​ចំណុច​ម៉ោនមូលដ្ឋាន​ដែនរង\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "ការ​ព្រមាន ៖ មិន​អាច​រក​ fs ដែល​សមរម្យ​នៅ​ក្នុង %s " "តើ​វា​ត្រូវ​បាន​ម៉ោន​ហើយ​ឬនៅ ?\n" "ប្រើ --subdomainfs ដើម្បី​បដិសេធ ។\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s ៖ សូម​ទោស ។ អ្នក​ត្រូវ​ការ​សិទ្ធិ​ជា root ដើម្បី​រត់​កម្មវិធី​នេះ ។\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s ៖ ​ព្រមាន ! អ្នក​បាន​កំណត់​កម្មវិធី​នេះជា setuid root ។\n" "អ្នក​ដែល​រត់​កម្មវិធី​នេះ អាច​ធ្វើ​ឲ្យ​ទម្រង់ AppArmor " "​របស់​អ្នក​ទាន់​សម័យ ។\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "កំហុស ៖ មិនអាច​អាន​ទម្រង់ %s: %s ។\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "កំហុស​បម្រុង​ទុក​សតិ ។" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s ៖ រក​ឃើញ​កំហុស​ក្នុង​ឯកសារ ។ បោះបង់ ។\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "ឧបករណ៍​​បញ្ជាក់​​គុណលក្ខណៈអក្សរ​​​ធំ​ \"RWLIMX\" ត្រូវ​បាន​បរិយាយ​ " "សូម​បម្លែង​វា​ទៅ​ជា​អក្សរ​តូច​វិញ​មើល​សេចក្ដី​លម្អិត​​ក្នុងទំព័រ​មេ​របស់​​ " "apparmor.d (៥​)  ​។\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "ប៉ះទង្កិច 'a' និង 'w' ដក​ចេញ​ដោយ​ដៃ ។" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Exec qualifier 'i' មិន​ត្រឹមត្រូវ​ឡើយ, qualifier " "ដែល​ប៉ះទង្គិច​ត្រូវ​បាន​បញ្ជាក់​រួច​ហើយ" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "មិន​បាន​​មានការ​បង្ខំ exec ដែល​មាន​គុណភាព​ (%c%c) " "ព័ត៌មាន​លម្អិត​អនុញ្ញាត​ឲ្យមាន​​អថេរបរិស្ថាន​គ្រោះ​ថ្នាក់​មួយ​ចំនួន​​ឆ្លង​កាត" "់​ដំណើរការ​ដែល​គ្មាន​ការ​បង្ខំ​ដោយ​ 'man ៥ apparmor.d'  ។\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Exec qualifier '%c' មិន​ត្រឹមត្រុវ ការ​ប៉ះទង្គិច​ qualifier already specified" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Exec qualifier '%c%c' មិន​ត្រឹមត្រូវ កា​រប៉ះទង្គិច​បាន​បញ្ជាក់​រួច​ហើយ" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "ខាង​ក្នុង ៖ តួអក្សរ​របៀប​ដែល​មិន​រំពឹង '%c' ក្នុង​ព័ត៌មាន​បញ្ចូល" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "កំហុស​ខាង​ក្នុង​បាន​បង្កើត​ perm មិន​ត្រឹមត្រូវ 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "កំហុស​ឧបករណ៍​ញែក AppArmor ៖ %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "ធាតុ​មិន​អាច​បញ្ចូល​ចូល​គ្នា​បាន​ឡើយ​ ។ អស់​សតិ\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "បាន​បរាជ័យ​ក្នុង​កា​របង្កើត​ឈ្មោះ​ក្លែងក្លាយ %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "ទង់​តម្រង់ 'បំបាត់​កំហុស' មិន​ត្រឹមត្រូវ​ទៀតទេ ។" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "ទង់​ទម្រង់​មិន​ត្រឹមត្រូវ ៖ %s ។" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "អះអាង ៖ `ច្បាប់' បាន​ត្រឡប់ NULL ។" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "របៀប​មិន​ត្រឹមត្រូវ 'x' មិន​ត្រូវ​​បន្ត​ដោយ exec qualifier 'i' 'u' ឬ 'p'" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "របៀប​មិន​ត្រឹមត្រូវ, 'x' ត្រូវ​តែ​បន្ត​ដោយ exec qualifier 'i', 'u' ឬ 'p'" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "របៀប​មិន​ត្រឹមត្រូវ, 'x' ត្រូវ​តែ​បន្ត​ដោយ exec qualifier 'i', 'u' ឬ 'p'" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "អះអាង ៖ `network_rule' ត្រឡប់​ពិធីការ​មិន​ត្រឹមត្រូវ ។" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "អះអាង ៖ `change_profile' ត្រឡប់ NULL ។" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "អះអាង ៖ 'ច្បាប់ hat' បាន​ត្រឡប់ NULL ។" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "អះអាង ៖ 'local_profile rule' returned NULL ។" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "អថេរ​ប៊ូលីន​មិន​កំណត់ %s បាន​ប្រើ​ក្នុង​កន្សោម if" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "unsafe rule missing exec permissions" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "សំណុំ​រង​អាច​ត្រូវ​បាន​ប្រើ​តែ​ជា​មួយ​ច្បាប់​តំណ​ប៉ុណ្ណោះ ។" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "តំណ និង exec perms ប៉ះទង្គិច​​ច្បាប់​ឯកសារ ដោយ​ប្រើ ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" "តំណ perms " "មិន​ត្រូវ​បាន​អនុញ្ញាត​នៅ​លើ​​ដំណើរការ​ផ្លាស់ប្ដូរ​ទម្រង់​ដែល​មានឈ្មោះ ។\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "បាត់​តួអក្សរ​ចុង​បន្ទាត់​មួយឬ ? (ធាតុ ៖ %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "ធាតុ​បណ្ដាញ​មិន​ត្រឹមត្រូវ ។" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "សមត្ថភាព​មិន​ត្រឹមត្រូវ %s ។" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" "%s ៖ ការ​បើក​មិន​ត្រឹមត្រូវ {, ការ​ដាក់​ជា​ក្រុម​ក្នុង​មិន​បាន​អនុញ្ញាត\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s ៖ កំហុស​ការ​ដាក់​កន្សោម​ធម្មតា​ជា​ក្រុម ៖ " "ចំនួន​ធាតុ​មិន​ត្រឹមត្រូវ​ចន្លោះ {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s ៖ កំហុស​ការ​ដាក់​កន្សោម​ធម្មតា​ជាក្រុម ៖ បិទ​មិន​ត្រឹមត្រូវ } " "មិន​ផ្គូផ្គង​នឹង​ការ​បើក { ដែល​បាន​រក​ឃើញ\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s ៖ Regex កំហុស​ការ​ដាក់​ជា​ក្រុម ៖ ការ​ដាក់​ជា​ក្រុម​ដែល​បាន​បិទ " "ឬ​ថ្នាក់​តួអក្សរ រំពឹង​ថា​បិទ }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" "%s ៖ បាន​រកឃើញ​សតិ​បណ្ដោះ​អាសន្ន​ខាង​ក្នុង​លើស​ចំណុះ បាន​លើសតួអក្សរ %d\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s ៖ មិន​អាច​ញែក​បន្ទាត់​បញ្ចូល '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" "កំហុស​ក្នុង​ការ​បញ្ចូល​ក្បួន​ចូល​គ្នា​សម្រាប់​ទម្រង់ %s " "បាន​បរាជ័យ​ក្នុង​ការ​ផ្ទុក\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "កំហុស​ទម្រង់ %s មាន​ធាតុ​គោល​នយោបាយដែល​មិន​អាច​ប្រើ​ជា​មួយ​នឹង​ខឺណែល​នេះ ៖\n" "\t'*', '?', ជួរ​តួអក្សរ និង​ការ​ជំនួស​មិន​ត្រូវ​បាន​អនុញ្ញាត ។\n" "\t'**' អាច​ត្រូវ​បាន​ប្រើ​តែ​នៅ​ចុង​ក្បួន​តែ​ប៉ុណ្ណោះ ។\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" "កំហុស​ក្នុង​ការ​ចូល​ដំណើរការ regexs សម្រាប់​ទម្រង់ %s " "បាន​បរាជ័យ​ក្នុង​ការ​ផ្ទុក\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "កំហុស ពង្រីក​អថេរ​សម្រាប់​ទម្រង់ %s បាន​បរាជ័យ​ក្នុង​​​ការ​ផ្ទុក\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "កំហុស​ក្នុង​​បន្ថែម​ច្បាប់​​ចូលដំណើរការ hat សម្រាប់​ទម្រង់ %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "កំហុស​ក្នុង​ទម្រង់ %s បាន​បរាជ័យ​ក្នុង​ការ​ផ្ទុក\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s ៖ មាន​​កំហុស​កំឡុង​ពេល​ដំណើរការ​បន្ទាប់ ។ បោះបង់ ។\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "%s ៖ មាន​កំហុស​កំឡុង​ពេល​ដំណើរ​ការ regex ជា​មុន ។ បោះបង់ ។\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s ៖ មាន​កំហុស​កំឡុង​ពេល​ដំណើរការ​បន្ទាប់ ។ បោះបង់ ។\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "%s ៖ រក​ឃើញ​កំហុស​ក្នុង​ច្បាប់​បន្សំ​ដំណើរការ​ជា​មុន ។ បោះបង់ ។\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/en_GB.po0000644000175000017500000006605113502024172014441 0ustar jjjj# English (United Kingdom) translation for apparmor # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2014-10-22 19:10+0000\n" "Last-Translator: Andi Chandler \n" "Language-Team: English (United Kingdom) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: en_GB\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Error: Out of memory.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Error: basedir %s is not a directory, skipping.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Error: Could not add directory %s to search path.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Error: Could not allocate memory.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Bad write position\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Permission denied\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Out of memory\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "Could not copy profile: Bad memory address\n" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profile does not conform to protocol\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profile does not match signature\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Profile version not supported by Apparmor module\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profile already exists\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profile doesn't exist\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "Permission denied; attempted to load a profile while confined?\n" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "Unknown error (%d): %s\n" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Unable to add \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Unable to replace \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Unable to remove \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Unable to write to stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "%s: Unable to write to output file\n" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: Invalid option: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Addition succeeded for \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Replacement succeeded for \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Removal succeeded for \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "profile %s network rules not enforced\n" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "Unknown pattern type\n" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Unable to open %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Memory Allocation Error: Unable to remove ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Memory Allocation Error: Unable to remove %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "unable to create work area\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "unable to serialise profile %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Unable to write entire profile entry\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "%s: Unable to write entire profile entry to cache\n" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "Could not open '%s'" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "fstat failed for '%s'" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "opendir failed '%s'" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "stat failed for '%s'" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "Could not open '%s' in '%s'" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Found unexpected character: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "Variable declarations do not accept trailing commas" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) Found unexpected character: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "Warning from %s (%s%sline %d): %s" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: Could not allocate memory for subdomainbase mount point\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Sorry. You need root privileges to run this programme.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Warning! You've set this programme setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Error: Could not read profile %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Memory allocation error." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "Cached load succeeded for \"%s\".\n" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "Cached reload succeeded for \"%s\".\n" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Errors found in file. Aborting.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to " "lowercase.\n" "See the apparmor.d(5) manpage for details.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Conflict 'a' and 'w' perms are mutually exclusive." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "Exec qualifier 'i' invalid, conflicting qualifier already specified." #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Exec qualifier '%c' invalid, conflicting qualifier already specified." #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified." #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Internal: unexpected mode character '%c' in input" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Internal error generated invalid perm 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "AppArmor parser error: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Couldn't merge entries. Out of Memory.\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "profile %s: has merged rule %s with conflicting x modifiers.\n" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "Profile attachment must begin with a '/'." #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Failed to create alias %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "Profile flag chroot_relative conflicts with namespace_relative" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "Profile flag mediate_deleted conflicts with delegate_deleted" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "Profile flag chroot_attach conflicts with chroot_no_attach" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "Profile flag 'debug' is no longer valid." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Invalid profile flag: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Assert: `rule' returned NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Invalid mode, in deny rules, 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'." #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'." #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'." #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Assert: `network_rule' return invalid protocol." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Assert: `change_profile' returned NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Assert: 'hat rule' returned NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Assert: 'local_profile rule' returned NULL." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Unset boolean variable %s used in if-expression" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "unsafe rule missing exec permissions" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "subset can only be used with link rules." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "link and exec perms conflict on a file rule using ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "link perms are not allowed on a named profile transition.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "missing an end of line character? (entry: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Invalid network entry." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Invalid capability %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "AppArmor parser error for %s%s%s at line %d: %s\n" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "AppArmor parser error, %s%s line %d: %s\n" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: Illegal open {, nesting groupings not allowed\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "%s: Regex grouping error: Invalid number of items between {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Internal buffer overflow detected, %d characters exceeded\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Unable to parse input line '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "%s: Invalid profile name '%s' - bad regular expression\n" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "ERROR merging rules for profile %s, failed to load\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "ERROR processing regexs for profile %s, failed to load\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "ERROR expanding variables for profile %s, failed to load\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "ERROR adding hat access rule for profile %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "ERROR in profile %s, failed to load\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: Errors found during postprocessing. Aborting.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "%s: Errors found during regex postprocess. Aborting.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: Errors found during postprocess. Aborting.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "%s: Errors found in combining rules postprocessing. Aborting.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "Could not process include directory '%s' in '%s'" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "Feature buffer full." #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "Out of memory" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "Cannot create cache directory: %s\n" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "File in cache directory location: %s\n" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "Cannot update cache directory: %s\n" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "Internal: unexpected DBus mode character '%c' in input" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "Internal error generated invalid DBus perm 0x%x\n" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "deny prefix not allowed" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "owner prefix not allowed" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "owner prefix not allow on mount rules" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "owner prefix not allow on dbus rules" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "owner prefix not allow on capability rules" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "invalid mount conditional %s%s" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "bad mount rule" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "mount point conditions not currently supported" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "invalid pivotroot conditional '%s'" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "%s: Regex grouping error: Exceeded maximum nesting of {}\n" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "ERROR processing policydb rules for profile %s, failed to load\n" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "ERROR replacing aliases for profile %s, failed to load\n" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "%s: Unable to write %s\n" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "Error: Could not read binary profile or cache file %s: %s.\n" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "Error: Could not read cache file '%s', skipping...\n" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "Internal: unexpected %s mode character '%c' in input" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "Internal error generated invalid %s perm 0x%x\n" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "owner prefix not allowed on mount rules" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "owner prefix not allowed on dbus rules" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "owner prefix not allowed on signal rules" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "owner prefix not allowed on ptrace rules" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "owner prefix not allowed on unix rules" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "owner prefix not allowed on capability rules" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "dbus rule: invalid conditional group %s=()" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "unix rule: invalid conditional group %s=()" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "%s: Regex error: trailing '\\' escape character\n" apparmor-2.13.3/parser/po/en_AU.po0000644000175000017500000005112413502024172014451 0ustar jjjj# English (Australia) translation for apparmor # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 22:00+0000\n" "Last-Translator: AppArmor list \n" "Language-Team: English (Australia) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: en_AU\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/id.po0000644000175000017500000006772713502024172014076 0ustar jjjj# Indonesian message file for YaST2 (@memory@). # Copyright (C) 2005 SUSE Linux Products GmbH. # Copyright (C) 2002 SuSE Linux AG. # Copyright (C) 1999-2001 SuSE GmbH. # I Made Wiryana , 1999. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2016-03-29 14:06+0000\n" "Last-Translator: Ari Setyo Wibowo \n" "Language-Team: Indonesian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: id\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Kesalahan: Memori tidak cukup.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Kesalahan: basedir %s bukan sebuah direktori, lewati.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" "Kesalahan: Tidak dapat menambahkan direktori %s ke lokasi pencarian.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Kesalahan: Tidak dapat mengalokasikan memori.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Posisi tulis yang buruk\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Izin ditolak\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Kehabisan memori\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "Tidak dapat menyalin profil: Alamat memori yang buruk\n" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profil tidak sesuai dengan protokol\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profil tidak cocok dengan signature\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Versi profil tidak didukung oleh Apparmor\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profil telah ada\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profil tidak ada\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "Izin ditolak; coba memuat profil walaupun dibatasi?\n" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "Kesalahan tak diketahui (%d): %s\n" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Tak dapat menambahkan \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Tak dapat menggantikan \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Tak dapat menghapus \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Tak dapat menuliskan ke stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "%s: Tak dapat menuliskan ke berkas output\n" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: Pilihan tidak benar: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Penambahan berhasil untuk \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Penggantian berhasil untuk \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Penghapusan berhasil untuk \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PANIC buffer increment yang buruk %p pos %p ext %p size %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "profil %s aturan jaringan tidak dilaksanakan\n" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "Jenis pola tak diketahui\n" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Tak dapat membuka %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Kesalahan Alokasi Memori: Tak dapat menghapus ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Kesalahan Alokasi Memori: Tak dapat menghapus %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "tak dapat membuat wilayah kerja\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "tak dapat menyambungkan profil %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Tak dapat menulis semua entri profil\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "%s: Tak dapat menulis semua entri profil untuk cache\n" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "Tak dapat membuka '%s'" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "fstat gagal untuk '%s'" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "opendir gagal '%s'" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "stat gagal untuk '%s'" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "Tak dapat membuka '%s' di '%s'" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Ditemukan karakter tak diharapkan: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "Deklarasi variabel tidak menerima beberapa koma berturutan" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) Ditemukan karakter tak diharapkan: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "Peringatan dari %s (%s%sline %d): %s" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: Tak dapat mengalokasikan memori untuk subdomainbase mount point\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Peringatan: tak dapat menemukan fs yang cocok di %s, apakah sudah di-mount?\n" "Gunakan --subdomainfs untuk override.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Maaf. Anda perlu izin root untuk menjalankan program ini.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Peringatan! Anda telah menentukan root untuk setuid program ini.\n" "Siapapun yang dapat menjalankan program ini dapat pula memutakhirkan profil " "AppArmor Anda.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Kesalahan: Tak dapat membaca prodil %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Kesalahan alokasi memori." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "Muatan cache berhasil untuk \"%s\".\n" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "Muat kembali cache berhasil untuk \"%s\".\n" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Kesalahan ditemukan di berkas. Membatalkan.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Kualifikasi huruf kapital \"RWLIMX\" telah usang, silakan ubah ke huruf " "kecil\n" "Lihat apparmor.d(5) manpage untuk rinciannya.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Konflik 'a' dan 'w' perms yang saling eksklusif." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Kualifikasi exec 'i' tidak benar, konflik dengan kualifikasi yang sudah " "ditentukan" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "Kualifikasi exec tak dibatasi (%c%c) mengixinkan beberapa environment " "variables berbahaya untuk diteruskan ke proses yang tak dibatasi; 'man 5 " "apparmor.d' untuk rinciannya.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Kualifikasi exec '%c' tak benar, konflik dengan kualifikasi yang sudah " "ditentukan" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Kualifikasi exec '%c%c' tak benar, konflik dengan kualifikasi yang sudah " "ditentukan" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Internal: karakter mode tak diharapkan '%c' di input" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Kesalahan internal menghasilkan perm tak benar 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "Kesalahan parser AppArmor: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Tak dapat menggabungkan entri. Kehabisan Memori\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "profil %s: telah menggabungkan aturan %s dengan konflik modifier x\n" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "Lampiran profil harus dimulai dengan sebuah '/'." #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" "Nama profil harus dimulai dengan sebuah '/', namespace atau kata kunci " "'profile' atau 'hat'." #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Gagal membuat alias %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "Bendera profil chroot_relative konflik dengan namespace_relative" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "Bendera profil mediate_deleted konflik dengan delegate_deleted" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" "Bendera prodil attach_disconnected konflik dengan no_attach_disconnected" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "Bendera profil chroot_attach konflik dengan chroot_no_attach" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "Bendera profil 'debug' tak lagi benar." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Bendera profil tak benar: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Assert: `rule' mengembalikan NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Mode tak benar, dalam menolak aturan 'x' harus tidak didahului dengan " "kualifikasi exec 'i', 'p', or 'u'" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Mode tak benar, 'x' harus didahului dengan kualifikasi exec 'i', 'p', 'c', " "or 'u'" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Mode tak benar, 'x' harus didahului dengan kualifikasi exec 'i', 'p', or 'u'" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Assert: `network_rule' mengembalikan protokol tak benar" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Assert: `change_profile' mengembalikan NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Assert: 'hat rule' mengembalikan NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Assert: 'local_profile rule' mengembalikan NULL." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Unset variabel boolean %s digunakan dalam if-expression" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "aturan tak aman kehilangan izin exec" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "subset hanya dapat digunakan dengan aturan link." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" "link dan exec perms konflik dalam sebuah aturan berkas yang menggunakan ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "link perms tidak diizinkan dalam sebuah transisi profil bernama.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "kehilangan sebuah karakter end of line? (entry: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Entri jaringan tak benar." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Kemampuan tak benar %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "Kesalahan parser AppArmor untuk %s%s%s pada baris %d: %s\n" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "Kesalahan parser AppArmor,%s%s baris %d: %s\n" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: pembukaan ilegal {, pengelompokan bertumpuk tak diizinkan\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: Kesalahan pengelompokan Regex: Angka tak benar dari item-item antara {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Kesalahan pengelompokan Regex: Penutupan tak benar }, tak ada pembukaan " "{ yang cocok terdeteksi\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Kesalahan pengelompokan Regex: Pengelompokan tak tertutup atau kelas " "karakter, mengharapkan penutupan }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Internal buffer overflow terdeteksi, %d karakter terlampaui\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Tak dapat parse baris input '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "%s: Nama profil tak benar '%s' - regular expression yang buruk\n" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "KESALAHAN menggabungkan aturan untuk profil %s, gagal memuat\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "KESALAHAN profil %s berisi kebijakan elemen yang tak dapat digunakan dengan " "kernel ini:\n" "\t'*', '?', jangkauan karakter, dan alternasi tak diizinkan.\n" "\t'**' hanya boleh digunakan pada akhir aturan.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "KESALAHAN memproses regexs untuk profil %s, gagal memuat\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "KESALAHAN mengembangkan variabel untuk profil %s, gagal memuat\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "KESALAHAN menambahkan aturan akses hat untuk profil %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "KESALAHAN di profil %s, gagal memuat\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: Kesalahan ditemukan saat postprocessing. Membatalkan.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "%s: Kesalahan ditemukan saat regex postprocess. Membatalkan.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: Kesalahan ditemukan saat postprocess. Membatalkan.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Kesalahan ditemukan saat menggabungkan aturan postprocessing. " "Membatalkan.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "Tak dapat memproses termasuk direktori '%s' in '%s'" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "Buffer fitur telah penuh." #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "Kehabisan memori" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "Tak dapat menciptakan direktori cache: %s\n" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "Berkas di lokasi direktori cache: %s\n" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "Tak dapat memutakhirkan direktori cache: %s\n" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "Internal: Karakter mode DBus tak diharapkan '%c' di input" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "Kesalahan internal menghasilkan DBus perm tak benar 0x%x\n" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "awalan menolak tak diizinkan" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "awalan pemilik tak diizinkan" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "awalan pemilik tak diizinkan pada aturan mount" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "awalan pemilik tak diizinkan pada aturan dbus" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "awalan pemilik tak diizinkan pada aturan kemampuan" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "Mount conditional tak benar %s%s" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "aturan mount yang buruk" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "kondisi mount point sedang tak didukung" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "Pivotroot conditional tak benar '%s'" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" "%s: Kesalahan pengelompokan Regex: Penutupan tak benar ], tak ada pembukaan " "[ terdeteksi\n" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "%s: Kesalahan pengelompokan Regex: Tumpukan {} melebihi maksimum\n" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "KESALAHAN memproses aturan policydb untuk profil %s, gagal memuat\n" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "KESALAHAN mengganti alias untuk profil %s, gagal memuat\n" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "%s: Gagal menuliskan %s\n" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" "Kesalahan: Tak dapat membaca profil binary atau berkas cache %s: %s.\n" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "Kesalahan: Tak dapat membaca berkas cache '%s', mengabaikan...\n" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "Internal: karakter mode %s tak diharapkan '%c' di input" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "Kesalahan internal menghasilkan %s perm 0x%x tak benar\n" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "awalan pemilik tak diizinkan pada aturan mount" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "awalan pemilik tak diizinkan pada aturan dbus" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "awalan pemilik tak diizinkan pada aturan signal" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "awalan pemilik tak diizinkan pada aturan ptrace" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "awalan pemilik tak diizinkan pada aturan unix" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "awalan pemilik tak diizinkan pada aturan kemampuan" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "aturan dbus: Kelompok conditional tak benar %s=()" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "aturan unix: Kelompok conditional tak benar %s=()" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "%s: Kesalahan Regex: membuntuti karakter escape '\\'\n" apparmor-2.13.3/parser/po/ms.po0000644000175000017500000006744713502024172014120 0ustar jjjj# Malay translation for apparmor # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2014-09-21 05:21+0000\n" "Last-Translator: abuyop \n" "Language-Team: Malay \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: ms\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Ralat: Kehabisan ingatan.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Ralat: basedir %s bukanlah direktori, melangkau.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Ralat: Tidak dapat tambah direktori %s untuk gelintar laluan.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Ralat: Tidak dapat peruntuk ingatan.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Kedudukan tulis teruk\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Keizinan dinafikan\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Kehabisan ingatan\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "Tidak dapat salin profil. Alamat ingatan teruk\n" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profil tidak menyebentuk ke protokol\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profil tidak sepadan dengan tandatangan\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Versi profil tidak disokong oleh modul Apparmor\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profil sudah wujud\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profil tidak wujud\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "Keizinan dinafikan; cuba untuk muatkan profil semasa dikurung?\n" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "Ralat tidak diketahui (%d): %s\n" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Tidak boleh tambah \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Tidak boleh ganti \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Tidak boleh buang \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Tidak boleh tulis ke stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "%s: Tidak boleh tulis ke fail output\n" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: Pilihan tidak sah: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Penambahan berjaya untuk \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Penggantian berjaya bagi \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Pembuangan berjaya bagi \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "penimbal tokokan teruk PANIC %p pos %p ext %p saiz %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "peraturan rangkaian profil %s tidak dikuat kuasakan\n" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "Jenis corak tidak diketahui\n" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Tidak boleh buka %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Ralat Peruntukan Ingatan: Tidak boleh buang ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Ralat Peruntukan Ingatan: Tidak boleh buang %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "tidak boleh cipta kawasan kerja\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "tidak boleh serialkan profil %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Tidak boleh tulis keseluruhan masukan profil\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "%s: Tidak boleh tulis keseluruhan masukan profil ke cache\n" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "Tidak dapat buka '%s'" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "fstat gagal bagi '%s'" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "opendir gagalkan '%s'" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "stat gagal bagi '%s'" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "Tidak dapat buka '%s' dalam '%s'" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Temui aksara tidak jangka: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "Deklarasi pembolehubah tidak menerima koma bertitik" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) Temui aksara tidak jangka: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "Amaran dari %s (%s%sbaris %d): %s" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: Tidak dapat peruntuk ingatan untuk titik lekap subdomainbase\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Amaran: tidak boleh cari fs yang sesuai dalam %s, adakah ia dilekap?\n" "Guna --subdomainfs untuk batalkan.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Maaf. Anda perlukan kelayakan root untuk jalankan program ini.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Amaran! Anda telah tetapkan root setuid program ini.\n" "Sesiapa sahaja boleh jalankan program ini boleh kemaskin profil AppArmor " "anda.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Ralat: Tidak dapat baca profil %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Ralat peruntukan ingatan." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "Berjaya muatkan cache untuk \"%s\".\n" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "Berjaya muatkan semula cache untuk \"%s\".\n" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Ralat ditemui dalam fail. Menghenti paksa.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Penerang huruf besar \"RWLIMX\" sudah lapok, sila tukar ia kepada huruf " "kecil\n" "Lihat halaman panduan apparmor.d(5) untuk perincian.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Konflik kekal 'a' dan 'w' adalah ekslusif secara bersama." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "Penerang exec 'i' tidak sah, penerang berkonflik sudah dinyatakan" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "Penerang exec tidak terkurung (%c%c) membolehkan beberapa pembolehubah " "persekitaran merbahaya melepasi ke proses tidak terkurung; 'man 5 " "apparmor.d' untuk perincian.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "Penerang exec '%c' tidak sah, penerang berkonflik sudah dinyatakan" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "Penerang exec '%c%c' tidak sah, penerang berkonflik sudah dinyatakan" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Dalaman: Mod aksara '%c' tidak dijangka dalam input" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Ralat dalaman menjana perm 0x%llx tidak sah\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "Ralat penghurai AppArmor: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Tidak dapat gabungkan masukan. Kehabisan Ingatan\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" "profil %s: mempunyai peraturan tergabung %s dengan penerang x yang " "berkonflik\n" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "Lampiran profil mesti bermula dengan tanda '/'." #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" "Nama profil mesti bermula dengan tanda '/', ruang nama atau kata kunci " "'profile' atau 'hat'." #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Gagal cipta alias %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "Bendera profil chroot_relative berkonflik dengan namespace_relative" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "Bendera profil mediate_deleted berkonflik dengan delegate_deleted" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" "Bendera profil attach_disconnected berkonflik dengan no_attach_disconnected" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "Bendera profil chroot_attach berkonflik dengan chroot_no_attach" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "Bendera profil 'nyahpepijat' tidak lagi sah." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Bendera profil tidak sah: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Terap:'rule' kembalikan NOL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Mod tidak sah, semasa menafikan peraturan 'x' tidak boleh didahului oleh " "penerang exec 'i', 'p', atau 'u'" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Mod tidak sah, 'x' mesti didahului oleh penerang exec 'i', 'p', 'c', atau 'u'" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Mod tidak sah, 'x' mesti didahului oleh penerang exec 'i', 'p', atau 'u'" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Terap: 'network_rule' kembalikan protokol tidak sah." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Terap: 'change_profile' kembalikan NOL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Terap: 'hat rule' kembalikan NOL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Terap: 'local_profile rule' kembalikan NOL." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Pembolehubah boolean %s tidak ditetap digunakan dalam ungkapan-if" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "peraturan tidak selamat kehilangan keizinan exec" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "subset hanya boleh digunakan dengan peraturan pautan." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "konflik kekal pautan dan exec pada peraturan fail menggunakan ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "perms pautan tidak dibenarkan pada peralihan profil bernama.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "hilang penghujung baris aksara? (masukan: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Masukan rangkaian tidak sah." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Keupayaan %s tidak sah." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "Ralat penghurai AppArmor untuk %s%s%s pada baris %d: %s\n" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "Ralat penghurai AppArmor, %s%s pada baris %d: %s\n" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" "%s: Pembuka { tidak dibolehkan, pengumpulan bersarang tidak dibenarkan\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: Ralat pengumpulan ungkapan nalar: Bilangan item tidak sah diantara {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Ralat pengumpulan ungkapan nalar: Penutup } tidak sah, tiada pembuka { " "yang sepadan dikesan\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Ralat pengumpulan ungkapan nalar: Pengumpulan atau kelas aksara tidak " "ditutup, menjangkakan penutup }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Penimbal dalaman melimpah dikesan, %d aksara terlebih\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Tidak boleh hurai baris input '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "%s: Nama profil '%s' tidak sah - ungkapan nalar teruk\n" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "RALAT menggabung peraturan untuk profil %s, gagal dimuatkan\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "RALAT profil %s mengandungi unsur polisi yang tidak boleh diguna oleh kernel " "ini:\n" "\tjulat aksara '*', '?', dan penyelangan tidak dibenarkan.\n" "\t'**' hanya boleh digunakan dihujung peraturan.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "RALAT memproses ungkapan nalar untuk profil %s, gagal dimuatkan\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "RALAT mengembangkan pembolehubah untuk profil %s, gagal dimuatkan\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "RALAT menambah peraturan capaian hat untuk profil %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "RALAT dalam profil %s, gagal dimuatkan\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: Ralat ditemui semasa pos-pemprosesan. Menghenti paksa.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" "%s: Ralat ditemui semasa pos-proses ungkapan nalar. Menghenti paksa.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: Ralat ditemui semasa pos-proses. Menghenti paksa.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Ralat ditemui semasa menggabungkan pos-pemprosesan peraturan. Menghenti " "paksa.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "Tidak dapat proses direktori include '%s' dalam '%s'" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "Penimbal fitur penuh." #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "Kehabisan ingatan" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "Tidak dapat cipta direktori cache: %s\n" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "Fail dalam lokasi direktori cache: %s\n" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "Tidak dapat kemaskini direktori cache: %s\n" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "Dalaman: aksara mod DBus '%c' tidak dijangka dalam input" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "Ralat dalaman dijana menjana DBus perm 0x%x tidak sah\n" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "nafi awalan tidak dibenarkan" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "awalan pemilik tidak dibenarkan" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "awalan pemilik tidak dibenarkan pada peraturan lekap" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "awalan pemilik tidak dibenarkan pada peraturan dbus" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "awalan pemilik tidak dibenarkan pada peraturan keupayaan" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "syarat lekap %s%s tidak sah" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "peraturan lekap teruk" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "syarat titik lekap buat masa ini tidak disokong" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "syarat pivotroot '%s' tidak sah" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" "%s: ralat pengumpulan ungkapan nalar: simbol ] tidak sah, tiada simbol [ " "dikesan\n" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" "%s: ralat pengumpulan ungkapan nalar: Penyarangan maksimum {} dicapai\n" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "RALAT memproses peraturan policydb bagi profil %s, gagal dimuatkan\n" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "RALAT menggantikan alias untuk profil %s, gagal dimuatkan\n" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "%s: Tidak boleh tulis %s\n" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "Ralat: Tidak dapat baca profil binari atau fail cache %s: %s.\n" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "Ralat: Tidak dapat baca fail cache '%s', melangkau...\n" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "Dalaman: mod %s aksara '%c' tidak dijangka dalam input" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "Ralat dalaman terjana %s tidak sah perm 0x%x\n" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "awalan pemilik tidak dibenarkan pada peraturan lekap" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "awalan pemilik tidak dibenarkan pada peraturan dbus" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "awalan pemilik tidak dibenarkan pada peraturan isyarat" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "awalan pemilik tidak dibenarkan pada peraturan ptrace" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "awalan pemilik tidak dibenarkan pada peraturan unix" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "awalan pemilik tidak dibenarkan pada peraturan keupayaan" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "peraturan dbus: kumpulan bersyarat %s=() tidak sah" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "peraturan unix: kumpulan bersyarat %s=() tidak sah" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "%s: Ralat ungkapan nalar: aksara '\\' escape\n" apparmor-2.13.3/parser/po/ro.po0000644000175000017500000006172213502024172014107 0ustar jjjj# translation of apparmor-parser.ro.po to # Romanian message file for YaST2 (@memory@). # Copyright (C) 2005 SUSE Linux Products GmbH. # Copyright (C) 2003 SuSE Linux AG. # # Stanciu-Lixandru Alec , 2007. msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 03:59+0000\n" "Last-Translator: Stanciu-Lixandru Alec \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: ro\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Eroare: Memorie insuficientă.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Eroare: basedir %s nu este un director, trec peste.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Eroare: Nu pot adăuga directorul %s la calea de căutare.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Eroare: nu pot aloca memorie.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Poziție de scriere incorectă\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Permisiune respinsă\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Memorie insuficientă\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profilul nu corespunde protocolului\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profilul nu corespunde cu semnătura\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Versiunea profilului nu este suportatp de modulul Apparmor\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profilul există deja\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profilul nu există\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Nu pot adăuga \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Nu pot înlocui \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Nu pot îndepărta \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Nu pot scrie la stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: Opțiune invalidă: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Adăugarea s-a efectuat pentru \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Înlocuirea s-a efectuat pentru \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Ștergerea s-a efectuat pentru \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "PANICĂ incrementare greșită buffer %p pos %p ext %p dimensiune %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Nu pot deschide %s -%s\n" # ############################################################################### # Old yast2-agents.po #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Eroare la alocarea memoriei: Nu pot șterge ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Eroare la alocarea memoriei: Nu pot șterge %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "nu pot crea spațiul de lucru\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "nu pot serializa profilul %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: No pot scrie intregul profil\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Am găsit un caracter neașteptat: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) Am găsit un caracter neașteptat: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: Nu pot aloca memorie pentru punctul de montare subdomainbase\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Atenție: nu pot găsi un fs potrivit în %s, este montat?\n" "Folosiți -subdomainfs pentru a forța.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Îmi pare rău. Aveți nevoie de privilegii root pentru a rula acest " "program.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Atenție! Ați setat setuid root pentru acest program.\n" "Oricine poate rula acest program poate face update la profilul dvs. " "AppArmor.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Eroare: Nu pot citi profilul %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Eroare la alocarea memoriei." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Am găsit erori în fișier. Abandonez.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Specificatori cu litere mari \"RWLIMX\" sunt depășiți, vă rog convertiți la " "litere mici\n" "Vedeți manpage apparmor.d(5) pentru amănunte.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Conflict 'a' și 'w' perms se exclud reciproc." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Specificatorul exec 'i' este invalid, specificatorul conflictual este deja " "definit" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Specificatorul exec '%c' este invalid, a fost deja declarat un asemenea " "specificator" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Specificatorul exec '%c%c' este invalid, a fost deja declarat un asemenea " "specificator" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Intern: '%c' este un caracter neașteptat la intrare" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "O eroare internă a generat permutarea invalidă 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "Eroare în parser-ul AppArmor: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Nu am putut uni intrările. Memorie insuficientă\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Nu am putut crea aliasul %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "Indicatorul 'debug' nu mai este valabil pentru profil." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Indicator de profil invalid: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Aserțiune: `regula' a întors NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Mod invalid, în regulile de interzicere 'x' nu trebuie precedat de " "specificatorul exec 'i', 'p' sau 'u'" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Mod invalid, 'x' trebuie să fie precedat de specificatorul exec 'i', 'p', " "'c' sau 'u'" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Mod invalid, 'x' trebuie precedat de specificatorul exec 'i', 'p' sau 'u'" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Ase_rțiune: `regula de rețea' a întors un protocol invalid." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Asețiune: `change_profile' a întors NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Aserțiune: `regulă _profil local' a întors NULL." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" "Variabila booleană neinițializată %s este folosită într-o instrucțiune if" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "regulă nesigură fără permisiuni de execuție" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "lipsește un caracter de sfârșit de linie? (intrare: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Capabilitate invalidă: %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" "%s: Paranteză { ilegală, nu sunt permise mai multe nivele de grupare\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: Eroare de grupare în expresia regulată: Număr invalid de intrări între " "{}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Eroare de grupare în expresia regulată: Paranteză închisă } invalidă, nu " "există nicio paranteză deschisă echivalentă\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Eroare de grupare în expresia regulată: Grupare sau clasă neterminată, " "mă așteptam la }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Am detectat o depășire a buffer-ului intern cu %d caractere\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Nu pot parsa linia '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "EROARE la unirea regulilor pentru profilul %s, nu am putut încărca\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "EROARE profilul %s conține elemente de politică ce nu pot fi utilizate cu " "acest kernel:\n" "\t'*','?', intervale de caractere și alternări nu sunt permise.\n" "\t'**' poate fi folosit doar la sfârșitul unei reguli.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" "EROARE la procesarea expresiilor regulate pentru profilul %s, încărcarea a " "eșuat\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" "EROARE la citirea variabilelor pentru profilul %s, nu am putut încărca\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "EROARE în profilul %s, încărcarea a eșuat\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: Au apărut erori în timpul post-procesării. Abandonez.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" "%s: Au apărut erori în timpul post-procesării expresiei regulate. " "Abandonez.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: Au apărut erori în timpul post-procesării. Abandonez.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Au apărut erori în combinarea regulilor de post-procesare. Abandonez.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/ca.po0000644000175000017500000005456613502024172014062 0ustar jjjj# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 01:59+0000\n" "Last-Translator: Christian Boltz \n" "Language-Team: Catalan\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: ca\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Posició d'escriptura incorrecta\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Permís denegat\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Sense memòria\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "El perfil no és compatible amb el protocol\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "El perfil no coincideix amb la signatura\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "El perfil ja existeix\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "El perfil no existeix\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: no es pot afegir \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: no es pot reemplaçar \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: no es pot eliminar \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: no es pot escriure a l'stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: confirmació: l'opció no vàlida: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "\"%s\" s'ha afegit correctament.\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "\"%s\" s'ha reemplaçat correctament.\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "\"%s\" s'ha eliminat correctament.\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "EMERGÈNCIA: increment incorrecte de la memòria intermèdia %p pos. %p ext. %p " "mida %d res. %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "No es pot obrir %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "no es pot crear l'àrea de treball\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "no es pot serialitzar el perfil %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: no es pot escriure tota l'entrada del perfil\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "S'ha trobat un caràcter inesperat: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: no s'ha pogut assignar memòria per al punt de muntatge de la base de " "subdomini\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "S'ha produït un error d'assignació de memòria." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: s'han detectat errors al fitxer. S'avortarà l'operació.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "El qualificador d'execució 'i' no és vàlid; entra en conflicte amb un " "qualificador ja especificat" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "No s'han pogut fusionar les entrades. Sense memòria\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Confirmació: `rule' ha retornat NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Confirmació: 'hat rule' ha retornat NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "falta un caràcter de final de línia? (entrada: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" "%s: l'obertura { no és vàlida, no es permet la imbricació d'agrupaments\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: s'ha produït un error d'agrupament d'expressions regulars: el nombre " "d'elements entre {} no és vàlid\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: s'ha produït un error d'agrupament d'expressions regulars: el tancament " "} no és vàlid; no s'ha detectat cap obertura { coincident\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" "%s: s'ha detectat un desbordament de la memòria intermèdia interna, s'han " "excedit %d caràcters\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: no es pot analitzar la línia d'entrada '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "ERROR al perfil %s, no s'ha pogut carregar\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: s'han detectat errors en combinar el postprocessament de regles. " "S'avortarà l'operació.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/th.po0000644000175000017500000005063513502024172014103 0ustar jjjj# Thai message file for YaST2 (@memory@). # Copyright (C) 2008 SUSE Linux Products GmbH. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 22:31+0000\n" "Last-Translator: i18n@suse.de\n" "Language-Team: Thai \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: th\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/hi.po0000644000175000017500000006073413502024172014071 0ustar jjjj# translation of apparmor-parser.hi.po to Hindi # Sangeeta Kumari , 2007. msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 02:49+0000\n" "Last-Translator: Sangeeta Kumari \n" "Language-Team: Hindi \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: hi\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "त्रुटि: याददाश्त के बाहर.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "त्रुटि: basedir %s एक निर्देशिका नहीं है, छोड़ रहा है.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "%s त्रुटि:खोज पथ के निर्देशिका में नहीं जोड़ सका .\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "त्रुटि: याददाश्त नहीं बांट सका.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "बुरी लेखन स्थिति\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "अनुमति देने से इंकार किया\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "स्मृति में नहीं है\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "प्रोफाइल प्रोटोकॉल की पुष्टि नहीं करता\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "प्रोफाइल हस्ताक्षर से मेल नहीं खाता\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "प्रोफाइल पहले से मौजूद है\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "प्रोफाइल मौजूद नहीं है\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: \"%s\" को जोड़ने में अक्षम। " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: \"%s\" को प्रतिस्थापित करने में अक्षम। " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: \"%s\" को हटाने में अक्षम। " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: stdout पर लिखने में अक्षम\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: अमान्य विकल्प : %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "\"%s\" के लिए जोड़ना सफल रहा।\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "\"%s\" के लिए प्रतिस्थापन सफल रहा।\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "\"%s\" के लिए हटाना सफल रहा।\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "पैनिक बैड इंक्रीमेंट बफर %p pos %p ext %p आकार %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "%s - %s को खोलने में अक्षम\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "कार्य क्षेत्र सृजित करने में अक्षम\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "प्रोफाइल %s को क्रमांकित करने में अक्षम\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: संपूर्ण प्रोफाइल प्रविष्टि को लिखने में अक्षम\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "अप्रत्याशित वर्ण मिला : '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: सबडोमेनबेस माउंट बिंदु के लिए स्मृति निर्धारित नहीं कर सका\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "त्रुटि: प्रोफाइल नहीं पढ़ सका %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "स्मृति निर्धारण त्रुटि।" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: फाइल में त्रुटियां प्राप्त हुईं। रद्द कर रहा है।\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Exec क्वालीफायर 'i' अमान्य है, टकरावकारी क्वालीफायर को पहले ही निर्दिष्ट कर " "दिया गया है" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "प्रविष्टियों को एक में नहीं मिला सकता। स्मृति में नहीं है\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Assert: `rule' NULL पर लौट आया।" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Assert: 'hat rule' NULL पर लौट आया।" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "लाइन के अंत का एक वर्ण छूटा है? (प्रविष्टि : %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: गैर-कानूनन खोलना {, नेस्टिंग ग्रुपिंग्स की अनुमति नहीं है\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "%s: Regex ग्रुपिंग त्रुटि : {} के बीच मदों की अमान्य संख्या\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Regex ग्रुपिंग त्रुटि : बंद अमान्य }, किसी मेल खाने वाले खोलने का { पता " "नहीं लगा\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: आंतरिक बफर के ओवरफ्लो होने का पता लगा, %d वर्ण अधिक हैं\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: इनपुट लाइन '%s' को पार्स करने में अक्षम\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "प्रोफाइल %s में त्रुटि है, लोड करने में असफल रहा\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: संयोगकारी नियमों के प्रसंस्करण-पश्चात में त्रुटियां प्राप्त हुईं। रद्द " "कर रहा है।\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/zu.po0000644000175000017500000005440313502024172014123 0ustar jjjj# English translations for subdomain_parser package. # Copyright (C) 2005 Immunix, Inc. # This file is distributed under the same license as the subdomain_parser package. # Steve Beattie , 2005. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 04:18+0000\n" "Last-Translator: Novell Language \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: zu\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Indawo yokukopisha enganembile\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Imvume inqatshiwe\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Ilahlekelwe Yimemori\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Iphrofayili ayivumelani nephrothokholi\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Iphrofayili ayifanelani nesignisha\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Iphrofayili isiyatholakala kakade\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Iphrofayili ayitholakali\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Ayikwazi ukwenezela i-\"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Ayikwazi ukushintsha i-\"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Ayikwazi ukususa i-\"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Ayikwazi ukukopishela kwi-stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: Okukhethiwe okuyiphutha: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Ukwenezela okulandelwe nge-\"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Ushintsho olulandelwe nge-\"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Ukususa okulandelwe nge-\"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "Ingobolwazi yesikhashana YOKUTATAZELA okubi %p pos %p ext %p size %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Ayikwazi ukuvula %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "Ayikwzi ukwakha indawo yokusebenzela\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "Ayikwazi ukwenza iphrofayili ibe nama-serial %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Ayikwazi ukuyibhala yonke iphrofayili\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Ithola uhlamvu olungalindelekile: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: Ayikwazanga ukuthola ingobolwazi yesixhakathisi se-domain engaphansi\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Iphutha lokwabiwa kwememori." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Amaphutha atholakale kwifayela. Iyayeka.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "I-exec qualifier u-‘i’ akasebenzi, i-qualifier engqubuzanayo isibonisiwe " "kakade" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Aykwazanga ukuhlanganisa ama-entry. Ilahlekelwe Yimemori\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Assert: `i-rule' ibuye IYIZE." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Assert: `i-hat rule’ ibuye IYIZE." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "ilahlekelwe yisiphetho sohlamvu lomugqa? (i-entry: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: Ukuvula okungekho emthethweni {, ukuvalela amaqoqo akuvunyelwe\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: Iphutha lokwenza amaqoqo le-regex: Inombolo eyiphutha yezinto " "eziphakathi nendawo {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Iphutha lokwenza amaqoqo le-regex: Ukuvala okuyiphutha }, akukho ukuvula " "okufanelanayo { ithungathwe yatholwa\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" "%s: Ingobolwazi yesikhashana yangaphakathi itholakele, %d izinhlamvu " "ezeqiwe\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Ayikwazi ukunqunta umugqa wokufakiwe '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "IPHUTHA kwiphrofayili %s, ihlulekile ukufaka\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Amaphutha atholakele ekuhlanganiseni imithetho yangemva kokuphrosesa. " "Iyayeka.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/ce.po0000644000175000017500000005107513502024172014056 0ustar jjjj# Chechen translation for apparmor # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the apparmor package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: apparmor\n" "Report-Msgid-Bugs-To: AppArmor list \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2014-08-13 08:08+0000\n" "Last-Translator: AppArmor list \n" "Language-Team: Chechen \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: ce\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/af.po0000644000175000017500000005411513502024172014053 0ustar jjjj# English translations for subdomain_parser package. # Copyright (C) 2005 Immunix, Inc. # This file is distributed under the same license as the subdomain_parser package. # Steve Beattie , 2005. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 01:27+0000\n" "Last-Translator: Novell Language \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: af\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Slegte skryfposisie\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Toelating geweier\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Geheue is opgebruik\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profiel pas nie aan by protokol nie\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profiel stem nie ooreen met handtekening nie\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profiel bestaan reeds\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profiel bestaan nie\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Kan \"%s\" nie byvoeg nie. " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Kan \"%s\" nie vervang nie. " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Kan \"%s\" nie verskuif nie. " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Kan nie na stdout toe skryf nie\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: BEWEER: Ongeldige opsie: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Byvoeging vir \"%s\" was suksesvol.\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Vervanging van \"%s\" was suksesvol.\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Verwydering van \"%s\" was suksesvol.\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PANIEK slegs inkrementbuffer %p pos %p uitbr %p grootte %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Kan %s - %s nie open nie\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "kan werkarea nie skep nie\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "kan profiel nie seriemaak nie %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Kan nie volledige profielinskrywing skryf nie\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Onverwagte karakter gevind: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: Kon geheue vir subdomeinbasis-hegpunt nie toeken nie\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Geheuetoekenningsfout." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Foute in lêer gevind. Staking.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Uitvoerende kwalifiseerder 'i' is ongeldig, konflikterende kwalifiseerder " "reeds gespesifisieer" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Kon inskrywings nie saamvleg nie. Geheue is opgebruik\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Beweer: `reël' het NUL teruggestuur." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Beweer: `hat-reël' het NUL teruggestuur." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "ontbreek daar ’n reëleindkarakter? (inskrywing: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: Onwettige open {, nesting van groeperings nie toegelaat nie\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "%s: Regex-groeperingsfout: Ongeldige aantal items tussen {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Regex-groeperingsfout: Ongeldige sluiting }, geen ooreenstemmende oop " "nie { bespeur\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Interne bufferoorvloei bespeur, %d karakters oorskry\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Kan insetreël '%s' nie ontleed nie\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "FOUT in profiel %s, het misluk om te laai\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Foute gevind in die kombineer van reëls tydens naprosessering. Staking.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/ta.po0000644000175000017500000006056013502024172014072 0ustar jjjjmsgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 03:28+0000\n" "Last-Translator: Priyavert \n" "Language-Team: AgreeYa Solutions\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: ta\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "மோசமான எழுதுநிலை\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "அனுமதி மறுக்கப்படுகிறது\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "நினைவில் இல்லை\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "விவரம் நெறிமுறையுடன் பொருந்தவில்லை\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "விவரம் கையொப்பத்துடன் பொருந்தவில்லை\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "விவரம் ஏற்கனவே உள்ளது\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "விவரம் இல்லை\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: \"%s\" சேர்க்க முடியவில்லை. " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: \"%s\" மாற்றியமைக்க முடியவில்லை. " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: \"%s\" நீக்க முடியவில்லை. " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: stdout-ல் எழுத முடியவில்லை\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: உறுதிசெய்தல்: செல்லாத விருப்பத்தேர்வு: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "\"%s\"க்கான கூடுதல் சேர்ப்பு வெற்றி பெற்றது.\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "\"%s\"க்கான மாற்று வெற்றி பெற்றது.\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "\"%s\"க்கான நீக்கம் வெற்றி பெற்றது.\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "பேனிக் மோசமான கூடுதல் பஃபர் %p pos %p ext %p அளவு %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "%s - %s திறக்க முடியவில்லை\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "பணி பகுதியை உருவாக்க முடியவில்லை\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "%s விவரத்தை வரிசைப்படுத்த முடியவில்லை\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: முழு விவர உள்ளீட்டையும் எழுத முடியவில்லை\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "எதிர்பாராத எழுத்தை கண்டுள்ளது: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "%s: துணைக்களதள ஏற்ற நிலைக்கு நினைவகத்தை ஒதுக்க முடியவில்லை\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "நினைவக ஒதுக்கீட்டு பிழை." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: கோப்பில் பிழைகள் உள்ளன. இடைனிருத்தப்படுகிறது.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "செயலாக்க தகுதி 'i' செல்லாது, முரண்படும் தகுதி ஏற்கனவே குறிப்பிடப்பட்டுள்ளது" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "உள்ளீடுகளை சேர்க்க முடியவில்லை. நினைவில் இல்லை\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "உறுதிசெய்தல்: ‘விதி’ மதிப்பின்றி திருப்பப்பட்டது." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "உறுதிசெய்தல்: ‘ஹேட் விதி’ மதிப்பின்றி திருப்பப்பட்டது." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "வரிசை எழுத்தின் முடிவு காணப்படவில்லை? (உள்ளீடு: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: சட்டவிரோத திறப்பு {, நெஸ்டிங் குழுக்களுக்கு அனுமதி இல்லை\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: ரீஜெக்ஸ் குழு சேர்ப்பில் பிழை: {} இடையிலான பொருட்களின் செல்லாத " "எண்ணிக்கை\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: ரீஜெக்ஸ் குழு சேர்ப்பில் பிழை: செல்லாத மூடுதல் }, பொருந்தும் திறப்பு { " "கண்டறியப்படவில்லை\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" "%s: உள் பஃபரின் வரம்புமீறல் கண்டறியப்பட்டுள்ளது, %d எழுத்துக்கள் " "மீறப்பட்டுள்ளன\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: உள்ளீட்டு வரி '%s'யை விளக்க முடியவில்லை\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "%s விவரத்தில் பிழை, எற்றுதல் தோல்வியுற்றது\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: பின்செயல்முறை விதிகளை இணைப்பதில் பிழைகள் உள்ளன. இடைனிருத்தப்படுகிறது.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/pl.po0000644000175000017500000006310513502024172014077 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 03:38+0000\n" "Last-Translator: Novell Language \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: pl\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Błąd: brak pamięci.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Błąd: katalog bazowy %s nie jest katalogiem. Pominięto.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" "Błąd: dodanie katalogu %s do ścieżki wyszukiwania nie powiodło się.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Błąd: przydzielenie pamięci nie powiodło się.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Nieprawidłowa pozycja zapisu\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Dostęp zabroniony\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Brak pamięci\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profil niezgodny z protokołem\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profil nie odpowiada sygnaturze\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Wersja profilu nie jest obsługiwana przez moduł Apparmor\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profil już istnieje\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profil nie istnieje\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: dodawanie \"%s\" nie powiodło się. " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: zamiana \"%s\" nie powiodła się. " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: usunięcie \"%s\" nie powiodło się. " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: zapis na wyjście standardowe nie powiódł się\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: nieprawidłowa opcja: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Dodanie dla \"%s\" zakończone powodzeniem.\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Zamiana dla \"%s\" zakończona powodzeniem.\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Usuwanie dla \"%s\" zakończone powodzeniem.\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "Nieprawidłowy bufor przyrostowy %p na pozycji %p ext %p rozmiar %d zasób %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Otwarcie %s nie powiodło się - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Błąd alokacji pamięci: Nie można usunąć ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Błąd alokacji pamięci: Nie można usunąć %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "Tworzenie obszaru roboczego nie powiodło się\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "Serializowanie profilu %s nie powiodło się\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: zapisanie całego profilu nie powiodło się\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Napotkano nieoczekiwany znak \"%s\"" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(tryb_sieciowy) napotkano nieoczekiwany znak: \"%s\"" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: przydzielenie pamięci dla punktu montowania bazy poddomeny nie powiodło " "się\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Uwaga: nie można znaleźć systemu plików w %s, czy jest on zamontowany?\n" "Opcja --subdomainfs wymusza typ systemu plików.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: do uruchomienia tego programu wymagane są uprawnienia administratora.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: uwaga - dla tego programu ustawiono flagę setuid root.\n" "Każdy użytkownik tego programu będzie mógł zmieniać profile AppArmor\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Błąd: nie można odczytać profilu %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Błąd przydzielenia pamięci." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: napotkano błędy w pliku. Przerwanie procesu.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Znaczniki zapisane wielkimi literami \"RWLIMX\" nie są już aktualne. Proszę " "używać\n" "małych liter. Więcej informacji można znaleźć w podręczniku systemowym " "apparmor.d(5).\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Konflikt - \"a\" i \"w\" wykluczają się wzajemnie." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Błędny znacznik wykonania \"i\". Wcześniej użyto sprzecznego znacznika." #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "Nieograniczony znacznik wykonania (%c%c) zezwala na przekazywanie " "niebezpiecznych zmiennych środowiska do procesu. Więcej informacji można " "znaleźć w podręczniku systemowym \"man 5 apparmor.d\".\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Błędny znacznik wykonania \"%c\". Wcześniej użyto sprzecznego znacznika." #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Błędny znacznik wykonania \"%c%c\", wcześniej użyto sprzecznego znacznika" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Błąd wewnętrzny: napotkano nieoczekiwany znak trybu \"%c\"" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" "Wewnętrzny błąd spowodował utworzenie nieprawidłowego uprawnienia 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "Błąd parsera AppArmor: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Łączenie wpisów nie powiodło się. Brak pamięci.\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Utworzenie aliasu %s nie powiodło się -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "Flaga profilu \"debug\" nie jest już prawidłowa." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Nieprawidłowa flaga profilu: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Asercja: 'rule' zwróciło NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Tryb nieprawidłowy, w regułach zabraniających znacznik \"x\" nie może być " "poprzedzony znacznikiem wykonania \"i\", \"p\" lub \"u\"" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Tryb nieprawidłowy, \"x\" należy poprzedzić znacznikiem wykonania \"i\", " "\"p\" lub \"u\"" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Tryb nieprawidłowy. Przed \"x\" należy użyć znacznika wykonania \"i\", " "\"p\" albo \"u\"." #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Asercja: \"network_rule\" zwróciło niepoprawny protokół." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Asercja: \"change_profile\" zwróciło NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Asercja: \"hat rule\" zwróciło NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Asercja: \"local_profile rule\" zwróciło NULL." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Nieustawiona zmienna logiczna %s użyta w wyrażeniu if." #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "niebezpieczna reguła bez uprawnień wykonania" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "podzbiór może być użyty tylko z regułami łączy." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "konflikt łączy i uprawnień wykonywania w regule pliku używającej ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" "uprawnienia odnośników nie są dozwolone w zmianie nazwanego profilu.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "brak znaku końca wiersza? (wpis: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Nieprawidłowy wpis sieciowy." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Nieprawidłowe uprawnienie %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" "%s: nieprawidłowy znak {. Zagnieżdżone grupowanie jest niedozwolone.\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: błąd grupowania wyrażeń regularnych: nieprawidłowa ilość elementów " "pomiędzy {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: błąd grupowania wyrażeń regularnych: nieprawidłowy znak }; nie " "znaleziono {\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: błąd grupowania wyrażeń regularnych: niedomknięte grupowanie; oczekiwano " "zamykającego }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: wewnętrzne przepełnienie bufora; przekroczono %d znaków\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: analiza wiersza \"%s\" nie powiodła się\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "Błąd łączenia reguł dla profilu %s. Wczytanie nie powiodło się.\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "Błąd: profil %s zawiera elementy zasad, które nie są używane w bieżącym\n" "\t jądrze systemu: zakresy znaków \"*\", \"?\" oraz zmiany nie są " "dozwolone.\n" "\t znak \"**\" może być użyty tylko na końcu reguły.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" "Błąd przetwarzania wyrażeń regularnych dla profilu %s. Wczytanie nie " "powiodło się.\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" "Błąd rozwijania zmiennych dla profilu %s. Wczytanie nie powiodło się.\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "Błąd podczas dodawania reguły dostępu hat dla profilu %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "Błąd w profilu %s. Wczytanie nie powiodło się.\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: Napotkano błędy podczas przetwarzania. Proces przerwano.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" "%s: Błąd podczas przetwarzania końcowego wyrażenia regularnego. Proces " "przerwano.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: Napotkano błędy podczas przetwarzania. Proces przerwano.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: napotkano błędy w łączonym przetwarzaniu reguł. Proces przerwano.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/hu.po0000644000175000017500000006433113502024172014102 0ustar jjjj# translation of apparmor-parser.hu.po to Hungarian # translation of apparmor-parser.hu.po to # translation of apparmor-parser.po to # Hungarian message File YaST2 (@memory@). # Copyright (C) 2005 SUSE Linux Products GmbH. # Copyright (C) 2002 SuSE Linux AG. # Copyright (C) 2000, 2001 SuSE GmbH. # # Marcel Hilzinger , 2001. # Sári Gábor , 2000. # Steve Varadi , 2000. # Zoltán Levárdy , 1999. # Papp Zsolt , 2006. # Kalman Kemenczy , 2006, 2007, 2008. # Ervin Novak , 2008. msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2015-04-03 18:34+0000\n" "Last-Translator: Úr Balázs \n" "Language-Team: Hungarian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: hu\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Hiba: nincs elég memória\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" "Hiba: a(z) %s alapkönyvtár nem érvényes könyvtár, ezért kihagyásra kerül.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" "Hiba: nem sikerült a(z) %s könyvtár hozzáadása a keresési útvonalhoz.\n" # modules/printconf/printconf_write_printer.ycp:30 # clients/printconf_write.ycp:308 #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Hiba: nem sikerült lefoglalni memóriát\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Rossz írási pozíció\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Engedély megtagadva\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Nincs elég memória\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "A profil nem felel meg a protokollnak\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "A profil nem egyezik az aláírással\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "A profil verzióját az AppArmor nem támogatja\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "A profil már létezik\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "A profil nem létezik\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: \"%s\" nem vehető fel. " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: \"%s\" nem cserélhető le. " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: \"%s\" nem távolítható el. " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Nem sikerült írni a standard kimenetre\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: Érvénytelen paraméter: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "\"%s\" hozzáadása sikerült.\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "\"%s\" cseréje sikerült.\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "\"%s\" eltávolítása sikerült.\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PÁNIK rossz növekmény puffer: %p poz: %p kit: %p méret %d felb: %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "%s nem nyitható meg - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Memóriafoglalási hiba: A(z) ^%s eltávolítása sikertelen\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Memóriafoglalási hiba. A(z) %s:%s eltávolítása sikertelen." # clients/lan_nfs_write.ycp:78 #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "a munkaterület létrehozása nem sikerült\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "A(z) %s profil sorba szedése nem sikerült\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Nem sikerült a teljes profilbejegyzés kiírása\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "„%s” nem nyitható meg" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Váratlan karakter: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) Váratlan karakter: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: Nem sikerült memóriát foglalni az aldomainbase csatolási pontnak\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Figyelem: A(z) %s nem tartalmaz megfelelő fájlrendszert, fel van csatolva?\n" "Ez a --subdomainfs paraméterrel írható felül.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Sajnálom. A program futtatásához root jogosultság szükséges.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Figyelem! A program setuid root módban futásra van állítva.\n" "Bárki, aki futtatja a programot, frissíteni tudja az AppArmor profilokat.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Hiba: A profil beolvasása sikertelen %s: %s\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Memóriafoglalási hiba." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Hiba a fájlban. A program leáll.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "A nagybetűs \"RWLIMX\" minősítők használata elavult, használjon kisbetűket.\n" "A részletekkel kapcsolatban lásd az apparmor.d(5) kézikönyvoldalt.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Ütközés: 'a' és 'w' kölcsönösen kizáró." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Az 'i' végrehajtás-módosító érvénytelen, már meg van adva egy ütköző minősítő" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "A korlátozás nélküli végrehajtás-minősítő (%c%c) lehetővé teszi egyes " "veszélyes környezeti változók átadását a korlátozás nélküli folyamatnak; a " "részletekkel kapcsolatban lásd a 'man 5 apparmor.d' kézikönyvoldalt.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "A(z) '%c' végrehajtás-módosító érvénytelen, már meg van adva egy ütköző " "minősítő" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "A(z) '%c%c' végrehajtás-módosító érvénytelen, már meg van adva egy ütköző " "minősítő" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Belső: váratlan módkarakter ('%c') a bemenetben" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "A belső hiba érvénytelen perm 0x%llx létrehozását okozta\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "AppArmor feldolgozási hiba: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "A bejegyzések nem fésülhetők össze. Nincs elég memória\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "%s -> %s álnév létrehozása sikertelen\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "A 'debug' profiljelző már nem érvényes." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Érvénytelen profiljelző: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Assert: A `rule' NULL értéket adott vissza." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Érvénytelen mód, az 'x' előtt az 'i', 'p' vagy 'u' végrehajtás-módosító " "kell, hogy álljon" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Érvénytelen mód, az 'x' előtt az 'i', 'p', 'c' vagy 'u' végrehajtás-módosító " "kell, hogy álljon" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Érvénytelen mód, az 'x' előtt az 'i', 'p' vagy 'u' végrehajtás-módosító " "kell, hogy álljon" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Assert: A `network_rule' érvénytelen protokollt adott vissza." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Assert: A `change_profile' NULL értéket adott vissza." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Assert: A 'hat rule' NULL értéket adott vissza." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Assert: A `local_profile rule' NULL értéket adott vissza." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Be nem állított logikai változó (%s) egy feltételes kifejezésben" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "nem biztonságos szabályból hiányzik a futtatási jogosultság" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "A részhalmaz csak a link szabályokkal használható." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "A link és futtatás jogosultságok ütköznek egy fájl szabályon ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" "link jogosultságok nem engedélyezettek egy nevezett profil átmenetében.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "Lehet, hogy hiányzik egy sorvége karakter? (bejegyzés: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Érvénytelen hálózati bejegyzés." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Érvénytelen tulajdonság: %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" "%s: Érvénytelen nyitott {, a csoportosítások nem ágyazhatók egymásba\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: Regex csoportosítási hiba: Érvénytelen számú elem a { és } között\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Regex csoportosítási hiba: Érvénytelen záró }, nem található hozzá " "tartozó nyitott {\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Regex csoportosítási hiba: Be nem zárt csoport, záró } hiányzik\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Belső puffer-túlcsordulás, %d karakterrel több\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: A '%s' bemeneti sor értelmezése nem sikerült\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" "HIBA a(z) %s profil szabályainak összefésülésénél, a betöltés nem sikerült\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "HIBA: a(z) %s profil ezzel a kernellel nem használható irányelvelemeket " "tartalmaz:\n" "\t'*', '?', karaktertartományok és alternatívák használata nem megengedett.\n" "\t'**' csak a szabály végén használható.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" "HIBA a(z) %s profil reguláris kifejezéseinek feldolgozásakor, a betöltés nem " "sikerült\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" "HIBA a(z) %s profil változóinak kibontásakor, a betöltés nem sikerült\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" "HIBA a hat hozzáférési szabály a(z) %s profilhoz való hozzáadásakor\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "HIBA a(z) %s profilban, a betöltés nem sikerült\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: Hibák az utófeldolgozás közben. A program leáll.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" "%s: Hibák a reguláris kifejezés utófeldolgozása közben. A program leáll.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: Hibák az utófeldolgozás közben. A program leáll.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Hiba a szabályok egyesítésének utófeldolgozásában. A program leáll.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/Makefile0000644000175000017500000000132713502024172014562 0ustar jjjj# ---------------------------------------------------------------------- # Copyright (c) 2004, 2005 NOVELL (All rights reserved) # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # ---------------------------------------------------------------------- all: # As translations get added, they will automatically be included, unless # the lang is explicitly added to DISABLED_LANGS; e.g. DISABLED_LANGS=en es DISABLED_LANGS= COMMONDIR=../../common include $(COMMONDIR)/Make-po.rules XGETTEXT_ARGS+=--language=C --keyword=_ $(shell if [ -f ${NAME}.pot ] ; then echo -n -j ; fi) apparmor-2.13.3/parser/po/uk.po0000644000175000017500000010233413502024172014101 0ustar jjjj# translation of apparmor-parser.po to Ukrainian # Translation of apparmor-parser.uk.po to Ukrainian # English translations for subdomain_parser package. # Copyright (C) 2005 Immunix, Inc. # This file is distributed under the same license as the subdomain_parser package. # # # Ivan Petrouchtchak , 2006, 2007. # Yuri Chornoivan , 2008, 2013. # Ivan Petrouchtchak , 2008. msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 12:27+0000\n" "Last-Translator: yurchor \n" "Language-Team: Ukrainian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: uk\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Помилка: недостатньо пам'яті.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Помилка: базовий каталог %s - це не каталог; пропускається.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Помилка: Не вдалося додати каталог %s до шляху пошуку.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Помилка: Не вдалося виділити пам'ять.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Погана позиція запису\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Відмовлено у доступі\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Не вистачає пам'яті\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "Не вдалося скопіювати профіль: помилкова адреса пам’яті\n" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Профіль не сумісний з протоколом\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Профіль не збігається з підписом\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Версія профілю не підтримується модулем Apparmor\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Профіль вже існує\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Профіль не існує\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" "Немає доступу. Здійснено спробу завантажити профіль у обмеженому режимі?\n" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "Невідома помилка (%d): %s\n" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Неможливо додати \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Неможливо замінити \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Неможливо вилучити \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Неможливо записати в stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "%s: не вдалося записати результати до файла\n" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: нечинний параметр: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Успішне додавання для \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Успішна заміна для \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Успішне вилучення для \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "PANIC неправильне збільшення буфера %p поз %p розш %p розм %d рес %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "правила щодо мережі профілю %s не буде застосовано примусово\n" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "Невідомий тип взірця\n" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Неможливо відкрити %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Помилка виділення пам'яті: Не вдалося вилучити ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Помилка виділення пам'яті: Неможливо вилучити %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "неможливо створити робочу ділянку\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "неможливо перетворити профіль %s в послідовну форму\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Не вдається записати повний запис профілю\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "%s: не вдалося записати увесь запис профілю до кешу\n" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "Не вдалося відкрити «%s»" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "помилка fstat під час обробки «%s»" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "помилка opendir під час оброби «%s»" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "помилка stat під час обробки «%s»" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "Не вдалося відкрити «%s» у «%s»" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Знайдено несподіваний символ: \"%s\"" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "У оголошеннях змінних не може бути завершальних ком" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) Знайдено неочікуваний символ: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "Попередження від %s (%s%sрядок %d): %s" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: Не вдалось виділити пам'ять для точки монтування основи піддомену\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Попередження: на %s не вдалося знайти відповідної файлової системи, може " "його не змонтовано?\n" "Використайте параметр --subdomainfs, щоб обійти проблему.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s: Для вживання цієї програми потрібні привілеї адміністратора.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Попередження! Ви вказали для цієї програми setuid root.\n" "Будь-хто, хто може запускати цю програму, може змінювати\n" "ваші профілі AppArmor.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Помилка: Не вдалось прочитати профіль %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Помилка виділення пам'яті." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "Успішне завантаження кешу для «%s».\n" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "Успішне перезавантаження кешу для «%s».\n" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: В файлі знайдені помилки. Переривається.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Класифікатори у верхньому регістрі \"RWLIMX\" не рекомендовано, будь ласка, " "переведіть їх у нижній регістр\n" "Перегляньте сторінку довідки apparmor.d(5), щоб дізнатися більше.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Конфлікт дозволів, 'a' та 'w' є взаємовиключними." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Класифікатор виконання «i» нечинний, попередньо визначено класифікатор, що " "конфліктує з ним" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "Необмежений класифікатор виконання (%c%c) дозволяє передачу деяких критичних " "змінних середовища необмеженому процесу; виконайте команду 'man 5 " "apparmor.d', щоб дізнатися більше.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Класифікатор виконання «%c» - нечинний, раніше визначено класифікатор, що з " "ним конфліктує" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Класифікатор виконання «%c%c» - нечинний, раніше визначено класифікатор, що " "з ним конфліктує" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Внутрішнє: неочікуваний символ режиму '%c' у вхідній інформації" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Внутрішня помилка, спричинена нечинним дозволом 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "Помилка аналізатора AppArmor: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Не вдалося об'єднати записи. Не вистачає пам'яті\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" "профіль %s: містить об’єднане правило %s з конфліктом x модифікаторів\n" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "Долучення до профілю має починатися з «/»." #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" "Назви профілів мають починатися з «/», назви простору назв або ключового " "слова «profile» чи «hat»." #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Не вдалося створити псевдонім %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "Прапорець профілю chroot_relative конфліктує з namespace_relative" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "Прапорець профілю mediate_deleted конфліктує з delegate_deleted" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" "Прапорець профілю attach_disconnected конфліктує з no_attach_disconnected" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "Прапорець профілю chroot_attach конфліктує з chroot_no_attach" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "Прапорець профілю \"debug\" більше не діє." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Нечинний прапорець профілю: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Виявлено: `rule' повернула NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Нечинний режим, перед «x» має бути вказано класифікатор виконання «i», «p», " "або «u»" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Нечинний режим, перед «x» має бути вказано класифікатор виконання «i», «p», " "«c» або «u»" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Нечинний режим, перед «x» має бути вказано класифікатор виконання «i», «p», " "або «u»" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Виявлено: «network_rule» повернула нечинний протокол." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Виявлено: `change_profile' повернула NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Виявлено: 'hat rule' повернула NULL." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Виявлено: `local_profile rule' повернула NULL." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Обнулення булівської змінної %s, яку використано в виразі умови" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "небезпечне правило без дозволів на виконання" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "підмножину можна використовувати лише з правилами посилань." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" "дозволи посилання і виконання конфліктують у правилі файлів за допомогою ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "дозволи посилань не дозволено для перенесення іменованого профілю.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "відсутній символ кінця рядка? (елемент: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Нечинний мережний елемент." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Нечинна характеристика %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "Помилка аналізатора AppArmor, %s%s%s, рядок %d: %s\n" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "Помилка аналізатора AppArmor,%s%s, рядок %d: %s\n" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" "%s: Неприпустима відкрита дужка {, вузлове групування не дозволяється\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: Помилка групування формального виразу: нечинна кількість пунктів у " "дужках {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Помилка групування формального виразу: нечинна завершальна дужка }, не " "знайдено відповідної початкової дужки {\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Помилка групування формального виразу: не завершено групу або клас " "символів, не знайдено завершальної дужки }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" "%s: Виявлено внутрішнє переповнення буфера, перевищення у %d символів\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Не вдається проаналізувати вхідний файл \"%s\"\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "%s: некоректна назва профілю, «%s» — помилковий формальний вираз\n" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" "ПОМИЛКА під час об’єднання правил для профілю %s, не вдалося завантажити\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "ПОМИЛКА! профіль %s містить елементи політики, що не можуть бути використані " "з цим ядром системи:\n" "\t'*', '?', діапазони символів і варіанти не дозволено.\n" "\tможна використовувати лише '**' наприкінці правила.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" "ПОМИЛКА обробки формальних виразів для профілю %s, не вдалося завантажити\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" "ПОМИЛКА при розширенні змінних для профілю %s; завантаження зазнало невдачі\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "ПОМИЛКА додавання правила доступу hat для профілю %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "ПОМИЛКА у профілі %s, не вдалося завантажити\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" "%s: У процесі остаточної обробки виявлено помилки. Аварійне завершення.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" "%s: У процесі остаточної обробки формального виразу виявлено помилки. " "Аварійне завершення.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" "%s: У процесі остаточної обробки виявлено помилки. Аварійне завершення.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Під час остаточної обробки складених правил виявлено помилки. Аварійне " "завершення.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "Не вдалося обробити каталог включення «%s» у «%s»" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "Переповнено буфер можливостей." #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "Недостатньо пам’яті" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "Не вдалося створити каталог кешу: %s\n" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "Файл на місці каталогу кешу: %s\n" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "Не вдалося оновити каталог кешу: %s\n" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" "Внутрішня помилка: неочікуваний символ режиму DBus, «%c», у вхідних даних" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "Внутрішня помилка, спричинена нечинними правами доступу DBus 0x%x\n" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "не можна використовувати префікс deny" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "не можна використовувати префікс owner" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "у правилах mount не можна використовувати префікс owner" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "у правилах dbus не можна використовувати префікс owner" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "у правилах capability не можна використовувати префікс owner" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "некоректна умова mount %s%s" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "помилкове правило mount" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "підтримки умов на точку монтування у поточній версії не передбачено" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "некоректна умова pivotroot, «%s»" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" "%s: помилка групування формального виразу: нечинна завершальна дужка ], не " "знайдено відповідної початкової дужки [\n" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" "%s: помилка групування формального виразу: перевищено максимальний рівень " "вкладеності у дужках {}\n" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" "ПОМИЛКА обробки правил policydb для профілю %s, не вдалося завантажити\n" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "ПОМИЛКА заміри псевдонімів для профілю %s, не вдалося завантажити\n" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/sk.po0000644000175000017500000005076613502024172014112 0ustar jjjj# translation of CheckHardware.po to Slovak # Copyright (C) 2003 Free Software Foundation, Inc. # Stanislav Visnovsky , 2003. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-14 22:30+0000\n" "Last-Translator: Stanislav Visnovsky \n" "Language-Team: Slovak \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: sk\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "" #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "" #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "" #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "" #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "" #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/xh.po0000644000175000017500000005523313502024172014106 0ustar jjjj# English translations for subdomain_parser package. # Copyright (C) 2005 Immunix, Inc. # This file is distributed under the same license as the subdomain_parser package. # Steve Beattie , 2005. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 04:04+0000\n" "Last-Translator: Novell Language \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:33+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: xh\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Indawo yokubhala engalunganga\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Imvume yaliwe\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Siphelile isithuba kuvimba wolwazi\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Inkangeleko yecala ayiyithobeli inkqubo elandelwayo\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Inkangeleko yecala ayingqinelani nomtyibelo\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Inkangeleko yecala seyikhona\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Inkangeleko yecala ayikho kwayona\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Akukwazeki ukufakela i-\"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Akukwazeki ukubeka okunye endaweni ye-\"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Akukwazeki ukushenxisa i-\"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Akukwazeki ukubhalela kwi-stdout\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: BANGA UBUNYANI: Isikhethwa esingasebenzisekiyo: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Ukufakela kuphumelele ukwenzela i-\"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Ukubeka okunye endaweni yokunye kuphumelele ukwenzela i-\"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Ukushenxisa kuphumelele ukwenzela i-\"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Ayikwazanga kuvuleka i-%s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "" #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "akukwazekanga ukudala indawo yomsebenzi\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "akukwazekanga ukulandelelanisa inkangeleko yecala ye-%s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "" "%s: Akukwazekanga ukubhala ungeniso olupheleleyo lwenkangeleko yecala\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Kufunyenwe uphawu oluthatha isithuba olungalindelekanga: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: Uvimba wolwazi akakwazanga kwabelwa indawo yogxumeko kwisiseko sommandla " "wolawulo owonganyelweyo\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Imposiso yokwabela okuthile uvimba wolwazi" #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Kufunyenwe iimposiso kwifayili. Kulahliwe.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "" #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Isichazi esiqhutywayo esingu-'i' asisebenziseki, isichazi esingquzulanayo " "sesixeliwe" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" "Amangeniso awakwazanga kumanyaniswa. Siphelile Isithuba Kuvimba Wolwazi\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "" #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "" #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Banga ubunyani: `umthetho' ubuyise OKUNGEYONTO." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "" #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "" #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Banga ubunyani: `umthetho we-hat' ubuyise OKUNGEYONTO." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "" #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "" #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "" "ulahlekelwe sisiphelo somgca wophawu oluthatha isithuba? (ungeniso: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "" #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "" #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" "%s: Ukuvula okungekho mthethweni {, amaqela azinziswe kokunye awavunyelwa\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: Imposiso yokubekwa ngokwamaqela kwe-regex: Inani lamanqaku " "elingasebenzisekiyo phakathi kwe-{}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Imposiso yokubekwa ngokwamaqela kwe-regex: ukuvala okungasebenzisekiyo " "}, akukho ngqinelwano luvulekileyo { luchongiweyo\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "" "%s: Kuchongwe ukuphuphuma kwangaphakathi kwesigcini sethutyana, %d " "zigqithisile iimpawu ezithatha izithuba\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "" "%s: Akukwazekanga ukwahlukanisa umgca wokungxalwa njengesiqalo '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "IMPOSISO kwinkangeleko yecala %s, isilele ukulayisha\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Kufunyenwe imposiso xa kudityaniswa imithetho ngethuba lakamva " "lokuqhubela phambili. Kulahliwe.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/da.po0000644000175000017500000006211013502024172014043 0ustar jjjj# translation of apparmor-parser.po to # # Martin Møller , 2005. # Jan Madsen , 2006. # Ib Larsen , 2006, 2007. # Martin Schlander , 2007. # Martin Schlander , 2008. msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2013-11-15 02:33+0000\n" "Last-Translator: Martin Schlander \n" "Language-Team: Danish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: da\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Fejl: Ikke mere hukommelse.\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Fejl: Udgangsmappe %s er ikke en mappe. Springer over.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "Fejl: Kunne ikke tilføje mappen %s til søgestien.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Fejl: Kunne ikke tildele hukommelse.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Dårlig skrive position\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Tilladelse nægtet\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Ikke mere hukommelse\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Profil passer ikke til protokol\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Profil stemmer ikke med signatur\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Profilversion er ikke understøttet af AppArmor-modulet\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profil eksisterer allerede\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profil eksisterer ikke\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Kunne ikke tilføje \"%s\". " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: Kunne ikke erstatte \"%s\". " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: Kunne ikke fjerne \"%s\". " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Ikke i stand til at skrive til standarduddata\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: PÅSTAND: Ugyldigt tilvalg: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Tilføjelse lykkedes for \"%s\".\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Erstatning lykkedes for \"%s\".\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Fjernelse lykkedes for \"%s\".\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "PANIK dårlig optællingsbuffer %p pos %p ext %p size %d res %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "Kunne ikke åbne %s - %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Fejl i allokering af hukommelse: Kunne ikke fjerne ^%s\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Fejl i allokering af hukommelse: Kunne ikke fjerne %s:%s." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "Ikke i stand til at oprette arbejdsområde\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "Ikke i stand til at serieordne profil %s\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Ikke i stand til at skrive hele profilindgangen\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Fundet uventet tegn: '%s'" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(netværk_tilstand) Fandt uventet tegn: '%s'" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s. Kunne ikke tildele hukommelse til underdomænegrundens monteringspunkt\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Advarsel: Ikke i stand til at finde et passende filsystem i %s, Er den " "monteret?\n" "Brug --subdomainfs for at tilsidesætte.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "%s. Desværre. Du skal have root-rettigheder for at køre dette program.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Advarsel! Du har sat programmets setuid til root.\n" "Enhver, der kan køre dette program, kan opdatere dine AppArmor-profiler.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Fejl: Kunne ikke læse profilen %s: %s.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Fejl i allokering af hukommelse." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "%s: Fundet fejl i filen. Afbryder.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Store bogstaver i tilladelser \"RWLIMX\" er forældet. Konverter venligst " "til små bogstaver\n" "Se apparmor.d(5) man-sider for detaljer.\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Konflikt, tilladelserne 'a' og 'w' er gensidigt udelukkende." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Kørselstilladelse 'i' er ugyldig. Konflikt med en allerede specificeret " "tilladelse" #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "Uindskrænket exec qualifier (%c%c) tillader at nogle farlige miljøvariabler " "overføres til den uindskrænkede proces. Se detaljer i 'man 5 apparmor.d'.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Kørselstilladelse '%c' er ugyldig. Konflikt med en allerede specificeret " "tilladelse" #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Kørselstilladelse '%c%c' er ugyldig. Konflikt med en allerede specificeret " "tilladelse" #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Intern: Uventet tilstandstegn '%c' i inddata" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Intern fejl genererede ugyldig tilladelse 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "AppArmor fortolkningsfejl: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "Kunne ikke sammenslutte indgange. Ikke mere hukommelse\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "" #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Kunne ikke oprette alias %s -> %s\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "Profilflaget 'debug' er ikke længere gyldigt." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Ugyldigt profilflag: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Påstand:`Regel' returneret NULL." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Ugyldig tilstand, i afvisningsregler må kørselstilladelse 'i', 'u' eller 'p' " "ikke gå forud for 'x'" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "Ugyldig tilstand, 'i', 'p', 'c' eller 'u' skal gå forud for 'x'" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "Ugyldig tilstand, 'i', 'u' eller 'p' skal gå forud for 'x'" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Påstand: 'network_rule' returnereer ugyldig protokol." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Påstand: 'change_profile' returnerede NULL." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Påstand: 'hatregel' returnerede NUL.L." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Påstand: 'local_profile rule' returnerede NULL." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "Fravalgt boolean-varibael %s brugt i et if-udtryk" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "usikker regel mangler eksekvértilladelser" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "subset kan kun bruges med linkregler." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "link- og kørselstilladelser konflikter om en filregel som bruger ->" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "linktilladelser er ikke tilladt på en navngiven profiltransition.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "mangler afslutningstegn i linjen? (Indgang %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Ugyldig netværkspunkt." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Ugyldig kapabilitet %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "%s: ulovlig åbning {, indlejrede grupperinger er ikke tilladt\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s. Grupperingsfejl i reg. udtryk: Ugyldig antal elementer mellem {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s. Grupperingsfejl i reg. udtryk: Ugyldig lukke }, ingen passende åbning { " "fundet\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s. Grupperingsfejl i reg. udtryk: Ikke lukket gruppering eller tegnklasse, " "forventer lukke }\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Intern bufferoverflow fundet, %d tegn overskredet\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Ikke i stand til at fortolke inddatalinje '%s'\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "FEJL: Sammenslutningsregel for profilen %s, indlæste ikke\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "FEJL: Profilen %s indeholder elementer i retningslinjerne, som ikke er " "brugbare med denne kerne:\n" "\t'*', '?', tegnområderne og lignende er ikke tilladt.\n" "\t'**' må kun bruges i slutningen af en regel.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "FEJL: Behandling af reg. udtryk for profilen %s blev ikke indlæst\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "FEJL: Udfoldning af variabler for profilen %s blev ikke indlæst\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "FEJL under tilføjelse af 'hat'-adgangsregel for profilen %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "FEJL i profilen %s. Blev ikke indlæst\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: Fejl fundet i efterbehandling. Afbryder.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "%s: Fejl fundet i efterbehandling af reg. udtryk. Afbryder.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: Fejl fundet i efterbehandling. Afbryder.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "%s. Fejl fundet i efterbehandling af kombineringsregler. Afbryder.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "" #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" apparmor-2.13.3/parser/po/de.po0000644000175000017500000007270713502024172014064 0ustar jjjj# Copyright (C) 2006 SuSE Linux Products GmbH, Nuernberg # This file is distributed under the same license as the package. # msgid "" msgstr "" "Project-Id-Version: apparmor-parser\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-13 00:11-0700\n" "PO-Revision-Date: 2018-04-06 14:39+0000\n" "Last-Translator: Tobias Bannert \n" "Language-Team: Novell Language \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2019-04-18 05:32+0000\n" "X-Generator: Launchpad (build 18928)\n" "Language: de\n" #: ../parser_include.c:113 ../parser_include.c:111 msgid "Error: Out of memory.\n" msgstr "Fehler: nicht genügend Speicher!\n" #: ../parser_include.c:123 ../parser_include.c:121 #, c-format msgid "Error: basedir %s is not a directory, skipping.\n" msgstr "Fehler: basedir »%s« ist kein Verzeichnis, es wird übersprungen.\n" #: ../parser_include.c:137 #, c-format msgid "Error: Could not add directory %s to search path.\n" msgstr "" "Fehler: Verzeichnis »%s« konnte nicht zu Suchpfad hinzugefügt werden.\n" #: ../parser_include.c:147 ../parser_include.c:151 msgid "Error: Could not allocate memory.\n" msgstr "Fehler: Es konnte kein Speicher zugeordnet werden.\n" #: ../parser_interface.c:69 ../parser_interface.c:72 ../parser_interface.c:49 msgid "Bad write position\n" msgstr "Ungültige Schreibposition\n" #: ../parser_interface.c:72 ../parser_interface.c:75 ../parser_interface.c:52 msgid "Permission denied\n" msgstr "Zugriff verweigert\n" #: ../parser_interface.c:75 ../parser_interface.c:78 ../parser_interface.c:55 msgid "Out of memory\n" msgstr "Nicht genügend Speicher!\n" #: ../parser_interface.c:78 ../parser_interface.c:81 ../parser_interface.c:58 msgid "Couldn't copy profile: Bad memory address\n" msgstr "Profil konnte nicht kopiert werden: falsche Speicheradresse\n" #: ../parser_interface.c:81 ../parser_interface.c:84 ../parser_interface.c:61 msgid "Profile doesn't conform to protocol\n" msgstr "Das Profil entspricht nicht dem Protokoll\n" #: ../parser_interface.c:84 ../parser_interface.c:87 ../parser_interface.c:64 msgid "Profile does not match signature\n" msgstr "Das Profil stimmt nicht mit der Signatur überein\n" #: ../parser_interface.c:87 ../parser_interface.c:90 ../parser_interface.c:67 msgid "Profile version not supported by Apparmor module\n" msgstr "Profilversion wird vom Apparmor-Modul nicht unterstützt\n" #: ../parser_interface.c:90 ../parser_interface.c:93 ../parser_interface.c:70 msgid "Profile already exists\n" msgstr "Profil ist bereits vorhanden\n" #: ../parser_interface.c:93 ../parser_interface.c:96 ../parser_interface.c:73 msgid "Profile doesn't exist\n" msgstr "Profil ist nicht vorhanden\n" #: ../parser_interface.c:96 ../parser_interface.c:99 ../parser_interface.c:76 msgid "Permission denied; attempted to load a profile while confined?\n" msgstr "" "Zugriff verweigert! Haben Sie versucht ein Profil zu laden, während Sie " "eingeschränkt waren?\n" #: ../parser_interface.c:99 ../parser_interface.c:102 ../parser_interface.c:79 #, c-format msgid "Unknown error (%d): %s\n" msgstr "Unbekannter Fehler (%d): %s\n" #: ../parser_interface.c:116 ../parser_interface.c:119 #: ../parser_interface.c:96 #, c-format msgid "%s: Unable to add \"%s\". " msgstr "%s: Hinzufügen von »%s« nicht möglich. " #: ../parser_interface.c:121 ../parser_interface.c:124 #: ../parser_interface.c:101 #, c-format msgid "%s: Unable to replace \"%s\". " msgstr "%s: »%s« kann nicht ersetzt werden. " #: ../parser_interface.c:126 ../parser_interface.c:129 #: ../parser_interface.c:106 #, c-format msgid "%s: Unable to remove \"%s\". " msgstr "%s: »%s« kann nicht entfernt werden. " #: ../parser_interface.c:131 ../parser_interface.c:134 #: ../parser_interface.c:111 #, c-format msgid "%s: Unable to write to stdout\n" msgstr "%s: Schreiben in Standardausgabe nicht möglich\n" #: ../parser_interface.c:135 ../parser_interface.c:138 #: ../parser_interface.c:115 #, c-format msgid "%s: Unable to write to output file\n" msgstr "%s: Schreiben in Ausgabedatei nicht möglich\n" #: ../parser_interface.c:138 ../parser_interface.c:162 #: ../parser_interface.c:141 ../parser_interface.c:165 #: ../parser_interface.c:118 ../parser_interface.c:142 #, c-format msgid "%s: ASSERT: Invalid option: %d\n" msgstr "%s: ASSERT: Ungültige Option: %d\n" #: ../parser_interface.c:147 ../parser_interface.c:150 #: ../parser_interface.c:127 #, c-format msgid "Addition succeeded for \"%s\".\n" msgstr "Hinzufügen für »%s« erfolgreich.\n" #: ../parser_interface.c:151 ../parser_interface.c:154 #: ../parser_interface.c:131 #, c-format msgid "Replacement succeeded for \"%s\".\n" msgstr "Ersetzungsvorgang für »%s« erfolgreich.\n" #: ../parser_interface.c:155 ../parser_interface.c:158 #: ../parser_interface.c:135 #, c-format msgid "Removal succeeded for \"%s\".\n" msgstr "Entfernen für »%s« erfolgreich.\n" #: ../parser_interface.c:251 ../parser_interface.c:254 #, c-format msgid "PANIC bad increment buffer %p pos %p ext %p size %d res %p\n" msgstr "" "PANIC - ungültiger Inkrement-Puffer %p Position %p Erweiterung %p Größe %d " "Auflösung %p\n" #: ../parser_interface.c:656 ../parser_interface.c:658 #: ../parser_interface.c:446 #, c-format msgid "profile %s network rules not enforced\n" msgstr "Netzwerkregeln für Profil %s werden nicht erzwungen\n" #: ../parser_interface.c:666 msgid "Unknown pattern type\n" msgstr "Unbekannter Mustertyp\n" #: ../parser_interface.c:750 ../parser_interface.c:902 #: ../parser_interface.c:743 ../parser_interface.c:894 #: ../parser_interface.c:518 ../parser_interface.c:669 #, c-format msgid "Unable to open %s - %s\n" msgstr "%s kann nicht geöffnet werden – %s\n" #: ../parser_interface.c:776 ../parser_interface.c:768 #: ../parser_interface.c:543 #, c-format msgid "Memory Allocation Error: Unable to remove ^%s\n" msgstr "Speicherzuordnungsfehler: ^%s kann nicht entfernt werden\n" #: ../parser_interface.c:789 ../parser_interface.c:781 #: ../parser_interface.c:556 #, c-format msgid "Memory Allocation Error: Unable to remove %s:%s." msgstr "Speicherzuordnungsfehler: %s:%s kann nicht entfernt werden." #: ../parser_interface.c:810 ../parser_interface.c:802 msgid "unable to create work area\n" msgstr "Arbeitsbereich kann nicht erstellt werden\n" #: ../parser_interface.c:818 ../parser_interface.c:810 #, c-format msgid "unable to serialize profile %s\n" msgstr "Serialisierung von Profil %s nicht möglich\n" #: ../parser_interface.c:829 ../parser_interface.c:916 #: ../parser_interface.c:821 ../parser_interface.c:908 #: ../parser_interface.c:582 #, c-format msgid "%s: Unable to write entire profile entry\n" msgstr "%s: Profileintrag kann nicht geschrieben werden\n" #: ../parser_interface.c:839 ../parser_interface.c:831 #: ../parser_interface.c:593 #, c-format msgid "%s: Unable to write entire profile entry to cache\n" msgstr "" "%s: Schreiben des gesamten Profileintrags in den Puffer nicht möglich\n" #: parser_lex.l:100 parser_lex.l:163 parser_lex.l:169 #, c-format msgid "Could not open '%s'" msgstr "»%s« konnte nicht geöffnet werden" #: parser_lex.l:104 parser_lex.l:167 parser_lex.l:173 #, c-format msgid "fstat failed for '%s'" msgstr "fstat fehlgeschlagen für »%s«" #: parser_lex.l:121 #, c-format msgid "opendir failed '%s'" msgstr "opendir fehlgeschlagen für »%s«" #: parser_lex.l:152 #, c-format msgid "stat failed for '%s'" msgstr "stat fehlgeschlagen für »%s«" #: parser_lex.l:155 parser_lex.l:133 parser_lex.l:139 #, c-format msgid "Could not open '%s' in '%s'" msgstr "»%s« konnte nicht in »%s« geöffnet werden" #: parser_lex.l:284 parser_lex.l:322 parser_lex.l:362 parser_lex.l:399 #: parser_lex.l:469 parser_lex.l:655 parser_lex.l:586 parser_lex.l:638 #, c-format msgid "Found unexpected character: '%s'" msgstr "Unerwartetes Zeichen gefunden: »%s«" #: parser_lex.l:386 parser_lex.l:418 parser_lex.l:428 msgid "Variable declarations do not accept trailing commas" msgstr "Variablendeklarationen dürfen nicht mit Kommata enden" #: parser_lex.l:420 #, c-format msgid "(network_mode) Found unexpected character: '%s'" msgstr "(network_mode) Unerwartetes Zeichen gefunden: »%s«" #: ../parser_main.c:333 ../parser_common.c:61 ../parser_common.c:106 #, c-format msgid "Warning from %s (%s%sline %d): %s" msgstr "Warnung aus %s (%s%sZeile %d): %s" #: ../parser_main.c:531 #, c-format msgid "%s: Could not allocate memory for subdomainbase mount point\n" msgstr "" "%s: Dem Einhängepunkt der Unterdomänenbasis konnte kein Speicher zugeordnet " "werden\n" #: ../parser_main.c:577 ../parser_main.c:616 ../parser_main.c:479 #, c-format msgid "" "Warning: unable to find a suitable fs in %s, is it mounted?\n" "Use --subdomainfs to override.\n" msgstr "" "Achtung: Es konnte kein geeignetes Dateisystem in »%s« gefunden werden. Ist " "es eingehängt?\n" "Verwenden Sie --subdomainfs, um es außer Kraft zu setzen.\n" #: ../parser_main.c:597 ../parser_main.c:635 ../parser_main.c:498 #, c-format msgid "" "%s: Sorry. You need root privileges to run this program.\n" "\n" msgstr "" "»%s«: Sie benötigen Systemverwalterrechte zum Ausführen dieses Programms.\n" "\n" #: ../parser_main.c:604 ../parser_main.c:642 ../parser_main.c:505 #, c-format msgid "" "%s: Warning! You've set this program setuid root.\n" "Anybody who can run this program can update your AppArmor profiles.\n" "\n" msgstr "" "%s: Achtung! Sie haben für dieses Programm »setuid root« festgelegt.\n" "Alle Personen, die dieses Programm ausführen, können Ihre AppArmor-Profile " "aktualisieren.\n" "\n" #: ../parser_main.c:704 ../parser_main.c:813 ../parser_main.c:836 #: ../parser_main.c:946 ../parser_main.c:860 #, c-format msgid "Error: Could not read profile %s: %s.\n" msgstr "Fehler: Profil »%s« konnte nicht gelesen werden: »%s«.\n" #: ../parser_main.c:718 ../parser_misc.c:270 parser_yacc.y:227 #: parser_yacc.y:374 parser_yacc.y:386 parser_yacc.y:484 parser_yacc.y:586 #: parser_yacc.y:624 parser_yacc.y:939 parser_yacc.y:948 parser_yacc.y:960 #: parser_yacc.y:1008 parser_yacc.y:1019 parser_yacc.y:1101 parser_yacc.y:1119 #: parser_yacc.y:1126 ../parser_main.c:850 ../parser_main.c:1015 #: ../parser_main.c:1229 ../parser_main.c:1283 ../parser_misc.c:431 #: parser_yacc.y:268 parser_yacc.y:416 parser_yacc.y:426 parser_yacc.y:537 #: parser_yacc.y:626 parser_yacc.y:976 parser_yacc.y:1021 parser_yacc.y:1030 #: parser_yacc.y:1042 parser_yacc.y:1078 parser_yacc.y:1082 parser_yacc.y:1092 #: parser_yacc.y:1102 parser_yacc.y:1201 parser_yacc.y:1223 parser_yacc.y:1234 #: parser_yacc.y:1309 parser_yacc.y:1327 parser_yacc.y:1334 parser_yacc.y:1385 #: ../parser_main.c:735 ../parser_main.c:923 ../parser_main.c:1133 #: ../parser_main.c:1187 parser_yacc.y:311 parser_yacc.y:462 parser_yacc.y:472 #: parser_yacc.y:583 parser_yacc.y:662 parser_yacc.y:669 parser_yacc.y:1130 #: parser_yacc.y:1166 parser_yacc.y:1170 parser_yacc.y:1180 parser_yacc.y:1190 #: parser_yacc.y:1298 parser_yacc.y:1376 parser_yacc.y:1479 parser_yacc.y:1490 #: parser_yacc.y:1565 parser_yacc.y:1583 parser_yacc.y:1590 parser_yacc.y:1639 #: ../network.c:314 ../af_unix.cc:203 msgid "Memory allocation error." msgstr "Speicherzuordnungsfehler." #: ../parser_main.c:740 ../parser_main.c:872 ../parser_main.c:757 #, c-format msgid "Cached load succeeded for \"%s\".\n" msgstr "Zwischengespeichertes Laden für »%s« erfolgreich.\n" #: ../parser_main.c:744 ../parser_main.c:876 ../parser_main.c:761 #, c-format msgid "Cached reload succeeded for \"%s\".\n" msgstr "Zwischengespeichertes Neuladen für »%s« erfolgreich.\n" #: ../parser_main.c:910 ../parser_main.c:1058 ../parser_main.c:967 #, c-format msgid "%s: Errors found in file. Aborting.\n" msgstr "" "%s: In der Datei wurde ein Fehler gefunden. Der Vorgang wird abgebrochen.\n" #: ../parser_misc.c:426 ../parser_misc.c:597 ../parser_misc.c:339 msgid "" "Uppercase qualifiers \"RWLIMX\" are deprecated, please convert to lowercase\n" "See the apparmor.d(5) manpage for details.\n" msgstr "" "Die groß geschriebenen Qualifier »RWLIMX« sind veraltet, bitte nutzen Sie " "klein geschriebene.\n" "Weitere Informationen auf der Handbuchseite apparmor.d(5).\n" #: ../parser_misc.c:467 ../parser_misc.c:474 ../parser_misc.c:638 #: ../parser_misc.c:645 ../parser_misc.c:380 ../parser_misc.c:387 msgid "Conflict 'a' and 'w' perms are mutually exclusive." msgstr "Die Parameter »a« und »w« schließen sich gegenseitig aus." #: ../parser_misc.c:491 ../parser_misc.c:662 ../parser_misc.c:404 msgid "Exec qualifier 'i' invalid, conflicting qualifier already specified" msgstr "" "Ausführungskennzeichner »i« ist ungültig, ein Kennzeichner, mit dem ein " "Konflikt besteht, wurde bereits angegeben." #: ../parser_misc.c:502 ../parser_misc.c:673 ../parser_misc.c:415 #, c-format msgid "" "Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n" msgstr "" "Nicht angebundener exec-Qualifier (%c%c) ermöglicht es einigen gefährlichen " "Umgebungsvariablen, an den unangebundenen Prozess übergeben zu werden; " "Einzelheiten mit »man 5 apparmor.d«.\n" #: ../parser_misc.c:510 ../parser_misc.c:551 ../parser_misc.c:681 #: ../parser_misc.c:722 ../parser_misc.c:423 ../parser_misc.c:464 #, c-format msgid "Exec qualifier '%c' invalid, conflicting qualifier already specified" msgstr "" "Ausführungskennzeichner »%c« ist ungültig, ein Kennzeichner, mit dem ein " "Konflikt besteht, wurde bereits angegeben." #: ../parser_misc.c:537 ../parser_misc.c:545 ../parser_misc.c:708 #: ../parser_misc.c:716 ../parser_misc.c:450 ../parser_misc.c:458 #, c-format msgid "" "Exec qualifier '%c%c' invalid, conflicting qualifier already specified" msgstr "" "Ausführungskennzeichner »%c%c« ist ungültig, ein Kennzeichner, mit dem ein " "Konflikt besteht, wurde bereits angegeben." #: ../parser_misc.c:593 ../parser_misc.c:764 ../parser_misc.c:506 #, c-format msgid "Internal: unexpected mode character '%c' in input" msgstr "Intern: Unerwartetes Moduszeichen »%c« in der Eingabe" #: ../parser_misc.c:615 ../parser_misc.c:786 ../parser_misc.c:528 #, c-format msgid "Internal error generated invalid perm 0x%llx\n" msgstr "Interner Fehler erzeugte ungültige Zugriffsrechte 0x%llx\n" #: ../parser_misc.c:865 ../parser_symtab.c:561 ../parser_regex.c:626 #: ../parser_variable.c:229 #, c-format msgid "AppArmor parser error: %s\n" msgstr "AppArmor-Analysefehler: %s\n" #: ../parser_merge.c:92 ../parser_merge.c:91 ../parser_merge.c:83 msgid "Couldn't merge entries. Out of Memory\n" msgstr "" "Einträge konnten nicht zusammengeführt werden. Kein Speicher vorhanden\n" #: ../parser_merge.c:111 ../parser_merge.c:113 ../parser_merge.c:105 #, c-format msgid "profile %s: has merged rule %s with conflicting x modifiers\n" msgstr "" "Profil %s: enthält zusammengeführte Regel %s mit in Konflikt stehenden x-" "Modifizierern\n" #: parser_yacc.y:236 parser_yacc.y:277 parser_yacc.y:320 msgid "Profile attachment must begin with a '/'." msgstr "Profilanhang muss mit einem »/« beginnen." #: parser_yacc.y:260 parser_yacc.y:302 parser_yacc.y:348 msgid "" "Profile names must begin with a '/', namespace or keyword 'profile' or 'hat'." msgstr "" "Profilnamen müssen mit einem »/«, Namensraum oder dem Schlüsselwort " "»profile« oder »hat« beginnen." #: parser_yacc.y:296 parser_yacc.y:338 parser_yacc.y:384 #, c-format msgid "Failed to create alias %s -> %s\n" msgstr "Alias %s → %s konnte nicht erstellt werden\n" #: parser_yacc.y:417 parser_yacc.y:460 parser_yacc.y:506 msgid "Profile flag chroot_relative conflicts with namespace_relative" msgstr "" "Profil-Marker chroot_relative steht in Konflikt mit namespace_relative" #: parser_yacc.y:421 parser_yacc.y:464 parser_yacc.y:510 msgid "Profile flag mediate_deleted conflicts with delegate_deleted" msgstr "Profil-Marker mediate_deleted steht in Konflikt mit delegate_deleted" #: parser_yacc.y:424 parser_yacc.y:467 parser_yacc.y:513 msgid "" "Profile flag attach_disconnected conflicts with no_attach_disconnected" msgstr "" "Profil-Marker attach_disconnected steht in Konflikt mit " "no_attach_disconnected" #: parser_yacc.y:427 parser_yacc.y:470 parser_yacc.y:516 msgid "Profile flag chroot_attach conflicts with chroot_no_attach" msgstr "Profil-Marker chroot_attach steht in Konflikt mit chroot_no_attach" #: parser_yacc.y:441 parser_yacc.y:484 parser_yacc.y:530 msgid "Profile flag 'debug' is no longer valid." msgstr "Profil-Marker »debug« ist nicht mehr gültig." #: parser_yacc.y:463 parser_yacc.y:506 parser_yacc.y:552 #, c-format msgid "Invalid profile flag: %s." msgstr "Ungültiger Profil-Marker: %s." #: parser_yacc.y:498 parser_yacc.y:520 parser_yacc.y:548 parser_yacc.y:594 msgid "Assert: `rule' returned NULL." msgstr "Assert: Für »rule« wurde NULL zurückgegeben." #: parser_yacc.y:501 parser_yacc.y:546 parser_yacc.y:552 parser_yacc.y:584 #: parser_yacc.y:598 parser_yacc.y:630 msgid "" "Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', " "'p', or 'u'" msgstr "" "Ungültiger Modus, in den Verweigernregeln darf vor »x« keiner der " "Ausführungskennzeichner »i«, »p« oder »u« stehen" #: parser_yacc.y:524 parser_yacc.y:556 parser_yacc.y:602 msgid "" "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'" msgstr "" "Ungültiger Modus, in Verbotsregeln muss vor »x« einer der exec-Qualifier " "»i«, »p«, »c« oder »u« stehen" #: parser_yacc.y:549 parser_yacc.y:587 parser_yacc.y:633 msgid "Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'" msgstr "" "Ungültiger Modus, in Verbotsregeln muss vor »x« einer der exec-Qualifier " "»i«, »p« oder »u« stehen" #: parser_yacc.y:574 parser_yacc.y:612 parser_yacc.y:614 parser_yacc.y:660 msgid "Assert: `network_rule' return invalid protocol." msgstr "Assert: Für »network_rule« wurde NULL zurückgegeben." #: parser_yacc.y:649 parser_yacc.y:696 parser_yacc.y:786 msgid "Assert: `change_profile' returned NULL." msgstr "Assert: Für »change_profile« wurde NULL zurückgegeben." #: parser_yacc.y:680 parser_yacc.y:720 parser_yacc.y:810 msgid "Assert: 'hat rule' returned NULL." msgstr "Assert: Für »hat rule« wurde NULL zurückgegeben." #: parser_yacc.y:689 parser_yacc.y:729 parser_yacc.y:819 msgid "Assert: 'local_profile rule' returned NULL." msgstr "Assert: Für »local_profile rule« wurde NULL zurückgegeben." #: parser_yacc.y:824 parser_yacc.y:885 parser_yacc.y:992 #, c-format msgid "Unset boolean variable %s used in if-expression" msgstr "In Bedingungssatz verwendete Boolsche-Variable »%s« deaktivieren" #: parser_yacc.y:882 parser_yacc.y:986 parser_yacc.y:1092 msgid "unsafe rule missing exec permissions" msgstr "Fehlende Ausführungsrechte bei unsicherer Regel" #: parser_yacc.y:901 parser_yacc.y:954 parser_yacc.y:1060 msgid "subset can only be used with link rules." msgstr "subset kann nur mit Link-Regeln verwendet werden." #: parser_yacc.y:903 parser_yacc.y:956 parser_yacc.y:1062 msgid "link and exec perms conflict on a file rule using ->" msgstr "" "Verknüpfungs- und Ausführungsberechtigungen stehen in Konflikt mit einer " "Dateiregel, in der »->« verwendet wird" #: parser_yacc.y:905 parser_yacc.y:958 parser_yacc.y:1064 msgid "link perms are not allowed on a named profile transition.\n" msgstr "" "Verknüpfungsberechtigungen sind bei einem benannten Profilübergang nicht " "erlaubt.\n" #: parser_yacc.y:921 parser_yacc.y:1003 parser_yacc.y:1109 #, c-format msgid "missing an end of line character? (entry: %s)" msgstr "Fehlt ein Zeilenumbruch? (Eintrag: %s)" #: parser_yacc.y:975 parser_yacc.y:985 parser_yacc.y:1057 parser_yacc.y:1067 #: parser_yacc.y:1145 parser_yacc.y:1155 msgid "Invalid network entry." msgstr "Ungültiger Netzwerkeintrag." #: parser_yacc.y:1039 parser_yacc.y:1048 parser_yacc.y:1254 parser_yacc.y:1510 #, c-format msgid "Invalid capability %s." msgstr "Ungültige Fähigkeit %s." #: parser_yacc.y:1066 parser_yacc.y:1269 parser_yacc.y:1525 #, c-format msgid "AppArmor parser error for %s%s%s at line %d: %s\n" msgstr "AppArmor-Analysefehler für %s%s%s in Zeile %d: %s\n" #: parser_yacc.y:1072 parser_yacc.y:1275 parser_yacc.y:1531 #, c-format msgid "AppArmor parser error,%s%s line %d: %s\n" msgstr "AppArmor-Analysefehler,%s%s Zeile %d: %s\n" #: ../parser_regex.c:244 #, c-format msgid "%s: Illegal open {, nesting groupings not allowed\n" msgstr "" "%s: Öffnen mit { ungültig, verschachtelte Gruppierungen sind nicht zulässig\n" #: ../parser_regex.c:265 ../parser_regex.c:274 ../parser_regex.c:278 #, c-format msgid "%s: Regex grouping error: Invalid number of items between {}\n" msgstr "" "%s: Regex-Gruppierungsfehler: Ungültige Anzahl an Einträgen zwischen {}\n" #: ../parser_regex.c:271 ../parser_regex.c:280 ../parser_regex.c:284 #, c-format msgid "" "%s: Regex grouping error: Invalid close }, no matching open { detected\n" msgstr "" "%s: Regex-Gruppierungsfehler: Ungültiges schließendes Zeichen }, kein " "passendes öffnendes Zeichen { gefunden\n" #: ../parser_regex.c:337 ../parser_regex.c:343 ../parser_regex.c:361 #, c-format msgid "" "%s: Regex grouping error: Unclosed grouping or character class, expecting " "close }\n" msgstr "" "%s: Regex-Gruppierungsfehler: Nicht abgeschlossene Gruppierung oder " "Zeichenklasse, abschließende } erwartet\n" #: ../parser_regex.c:351 ../parser_regex.c:357 #, c-format msgid "%s: Internal buffer overflow detected, %d characters exceeded\n" msgstr "%s: Interner Pufferüberlauf erkannt, %d Zeichen überschritten\n" #: ../parser_regex.c:355 ../parser_regex.c:361 ../parser_regex.c:377 #, c-format msgid "%s: Unable to parse input line '%s'\n" msgstr "%s: Eingabezeile »%s« kann nicht analysiert werden\n" #: ../parser_regex.c:397 ../parser_regex.c:405 ../parser_regex.c:421 #, c-format msgid "%s: Invalid profile name '%s' - bad regular expression\n" msgstr "%s: Ungültiger Profilname »%s« – Fehlerhafter regulärer Ausdruck\n" #: ../parser_policy.c:202 ../parser_policy.c:402 ../parser_policy.c:375 #, c-format msgid "ERROR merging rules for profile %s, failed to load\n" msgstr "FEHLER Vereinigungsregeln für Profil »%s«, Laden gescheitert\n" #: ../parser_policy.c:234 #, c-format msgid "" "ERROR profile %s contains policy elements not usable with this kernel:\n" "\t'*', '?', character ranges, and alternations are not allowed.\n" "\t'**' may only be used at the end of a rule.\n" msgstr "" "FEHLER Das Profil %s enthält Richtlinienelemente, die mit diesem Kernel " "nicht verwendet werden können:\n" "\t»*«, »?«, Zeichenbereiche und alternierende Sprachsetzung sind nicht " "erlaubt.\n" "\t»**« kann am Ende einer Regel verwendet werden.\n" #: ../parser_policy.c:279 ../parser_policy.c:359 ../parser_policy.c:332 #, c-format msgid "ERROR processing regexs for profile %s, failed to load\n" msgstr "FEHLER Verarbeitung der Regexs für Profil »%s«, Laden gescheitert\n" #: ../parser_policy.c:306 ../parser_policy.c:389 ../parser_policy.c:362 #, c-format msgid "ERROR expanding variables for profile %s, failed to load\n" msgstr "" "FEHLER beim Erweitern der Variablen für Profil »%s«, Laden gescheitert\n" #: ../parser_policy.c:390 ../parser_policy.c:382 ../parser_policy.c:355 #, c-format msgid "ERROR adding hat access rule for profile %s\n" msgstr "FEHLER Hinzufügen von »hat«-Zugriffsregel für Profil %s\n" #: ../parser_policy.c:490 ../parser_policy.c:271 #, c-format msgid "ERROR in profile %s, failed to load\n" msgstr "FEHLER in Profil %s, konnte nicht geladen werden\n" #: ../parser_policy.c:675 #, c-format msgid "%s: Errors found during postprocessing. Aborting.\n" msgstr "%s: Fehler bei der Nachbearbeitung. Vorgang wird abgebrochen.\n" #: ../parser_policy.c:682 ../parser_policy.c:704 #, c-format msgid "%s: Errors found during regex postprocess. Aborting.\n" msgstr "" "%s: Während der Nachverarbeitung der regulären Ausdrücke sind Fehler " "aufgetreten. Vorgang wird abgebrochen.\n" #: ../parser_policy.c:689 #, c-format msgid "%s: Errors found during postprocess. Aborting.\n" msgstr "%s: Fehler bei der Nachbearbeitung. Vorgang wird abgebrochen.\n" #: ../parser_policy.c:696 #, c-format msgid "%s: Errors found in combining rules postprocessing. Aborting.\n" msgstr "" "%s: Beim Kombinieren von Regeln in der Nachverarbeitung sind Fehler " "aufgetreten. Der Vorgang wird abgebrochen.\n" #: parser_lex.l:180 parser_lex.l:186 #, c-format msgid "Could not process include directory '%s' in '%s'" msgstr "" "Das enthaltene Verzeichnis »%s« in »%s« kann nicht verarbeitet werden" #: ../parser_main.c:660 ../parser_main.c:523 msgid "Feature buffer full." msgstr "Funktionspuffer ist voll." #: ../parser_main.c:1115 ../parser_main.c:1132 ../parser_main.c:1024 #: ../parser_main.c:1041 msgid "Out of memory" msgstr "Nicht genügend Speicher!" #: ../parser_main.c:1182 ../parser_main.c:1091 #, c-format msgid "Can't create cache directory: %s\n" msgstr "Pufferverzeichnis kann nicht erstellt werden: %s\n" #: ../parser_main.c:1185 ../parser_main.c:1094 #, c-format msgid "File in cache directory location: %s\n" msgstr "Datei im Pufferverzeichnisort: %s\n" #: ../parser_main.c:1188 ../parser_main.c:1097 #, c-format msgid "Can't update cache directory: %s\n" msgstr "Pufferverzeichnis kann nicht aktualisiert werden: %s\n" #: ../parser_misc.c:833 #, c-format msgid "Internal: unexpected DBus mode character '%c' in input" msgstr "Intern: Unerwartetes D-Bus-Moduszeichen »%c« in der Eingabe" #: ../parser_misc.c:857 #, c-format msgid "Internal error generated invalid DBus perm 0x%x\n" msgstr "Interner Fehler hat ungültige D-Bus-Zugriffsrechte 0x%x erstellt\n" #: parser_yacc.y:575 parser_yacc.y:621 msgid "deny prefix not allowed" msgstr "Verweigernpräfix nicht erlaubt" #: parser_yacc.y:612 parser_yacc.y:658 msgid "owner prefix not allowed" msgstr "Eigentümerpräfix nicht erlaubt" #: parser_yacc.y:660 msgid "owner prefix not allow on mount rules" msgstr "Eigentümerpräfix nicht bei Einhängeregeln erlauben" #: parser_yacc.y:677 msgid "owner prefix not allow on dbus rules" msgstr "Eigentümerpräfix nicht bei D-Bus-Regeln erlauben" #: parser_yacc.y:704 msgid "owner prefix not allow on capability rules" msgstr "Eigentümerpräfix nicht bei Fähigkeitsregeln erlauben" #: parser_yacc.y:1357 parser_yacc.y:1613 #, c-format msgid "invalid mount conditional %s%s" msgstr "Ungültige Einhängebedingung %s%s" #: parser_yacc.y:1374 parser_yacc.y:1628 msgid "bad mount rule" msgstr "Ungültige Einhängeregel" #: parser_yacc.y:1381 parser_yacc.y:1635 msgid "mount point conditions not currently supported" msgstr "Einhängepunktbedingungen werden derzeit nicht unterstützt" #: parser_yacc.y:1398 parser_yacc.y:1650 #, c-format msgid "invalid pivotroot conditional '%s'" msgstr "Ungültige pivotroot-Bedingung »%s«" #: ../parser_regex.c:241 ../parser_regex.c:236 #, c-format msgid "" "%s: Regex grouping error: Invalid close ], no matching open [ detected\n" msgstr "" "%s: Regex-Gruppierungsfehler: Ungültiges schließendes Zeichen ], kein " "passendes öffnendes Zeichen [ gefunden\n" #: ../parser_regex.c:257 ../parser_regex.c:256 #, c-format msgid "%s: Regex grouping error: Exceeded maximum nesting of {}\n" msgstr "" "%s: Regex-Gruppierungsfehler: maximale Verschachtelung von {} überschritten\n" #: ../parser_policy.c:366 ../parser_policy.c:339 #, c-format msgid "ERROR processing policydb rules for profile %s, failed to load\n" msgstr "" "FEHLER beim Verarbeiten der policydb-Regeln für das Profil %s. Das Laden ist " "fehlgeschlagen.\n" #: ../parser_policy.c:396 ../parser_policy.c:369 #, c-format msgid "ERROR replacing aliases for profile %s, failed to load\n" msgstr "" "FEHLER beim ersetzen der Aliasse für Profil %s. Das Laden ist " "fehlgeschlagen\n" #: ../parser_interface.c:635 ../parser_interface.c:638 #, c-format msgid "%s: Unable to write %s\n" msgstr "%s: Nicht in der Lage %s zu schreiben\n" #: ../parser_main.c:721 #, c-format msgid "Error: Could not read binary profile or cache file %s: %s.\n" msgstr "" "Fehler: Binär- oder Zwischenspeicherdatei kann nicht gelesen werden %s: %s.\n" #: ../parser_main.c:811 #, c-format msgid "Error: Could not read cache file '%s', skipping...\n" msgstr "" "Fehler: Pufferdatei kann nicht gelesen werden »%s« - es wird übersprungen …\n" #: ../parser_misc.c:575 #, c-format msgid "Internal: unexpected %s mode character '%c' in input" msgstr "Intern: Unerwartetes %s-Moduszeichen »%c« in der Eingabe" #: ../parser_misc.c:599 #, c-format msgid "Internal error generated invalid %s perm 0x%x\n" msgstr "Interner Fehler hat ungültige %s-Zugriffsrechte 0x%x erstellt\n" #: parser_yacc.y:703 msgid "owner prefix not allowed on mount rules" msgstr "Eigentümerpräfix ist nicht bei Einhängeregeln erlaubt" #: parser_yacc.y:720 msgid "owner prefix not allowed on dbus rules" msgstr "Eigentümerpräfix ist nicht bei D-Bus-Regeln erlaubt" #: parser_yacc.y:736 msgid "owner prefix not allowed on signal rules" msgstr "Eigentümerpräfix ist nicht bei Signalregeln erlaubt" #: parser_yacc.y:752 msgid "owner prefix not allowed on ptrace rules" msgstr "Eigentümerpräfix ist nicht bei ptrace-Regeln erlaubt" #: parser_yacc.y:768 msgid "owner prefix not allowed on unix rules" msgstr "Eigentümerpräfix ist nicht bei UNIX-Regeln erlaubt" #: parser_yacc.y:794 msgid "owner prefix not allowed on capability rules" msgstr "Eigentümerpräfix ist nicht bei Fähigkeitsregeln erlaubt" #: parser_yacc.y:1293 #, c-format msgid "dbus rule: invalid conditional group %s=()" msgstr "D-Bus-Regel: ungültige Bedingungsgruppe %s=()" #: parser_yacc.y:1371 #, c-format msgid "unix rule: invalid conditional group %s=()" msgstr "UNIX-Regel: ungültige Bedingungsgruppe %s=()" #: ../parser_regex.c:368 #, c-format msgid "%s: Regex error: trailing '\\' escape character\n" msgstr "" "%s: Fehler im regulären Ausdruck: Schrägstrich »\\« ist ein " "Ausschlusszeichen\n" apparmor-2.13.3/parser/rule.cc0000644000175000017500000000142213502024172013756 0ustar jjjj/* * Copyright (c) 2014 * Canonical Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical * Ltd. */ #include "rule.h" std::ostream &operator<<(std::ostream &os, rule_t &rule) { return rule.dump(os); }; apparmor-2.13.3/parser/mount.cc0000644000175000017500000005414413502024172014162 0ustar jjjj/* * Copyright (c) 2010 * Canonical, Ltd. (All rights reserved) * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, contact Novell, Inc. or Canonical * Ltd. */ /** * The mount command, its mix of options and flags, its permissions and * mapping are a mess. * mount [-lhV] * * mount -a [-fFnrsvw] [-t vfstype] [-O optlist] * * mount [-fnrsvw] [-o option[,option]...] device|dir * * mount [-fnrsvw] [-t vfstype] [-o options] device dir * *---------------------------------------------------------------------- * Mount flags of no interest for apparmor mediation * -a, --all * -F fork for simultaneous mount * -f fake, do everything except that actual system call * -h --help * -i, --internal-only * -n mount without writing in /etc/mtab * -O limits what is auto mounted * -p, --pass-fd num * -s Tolerate sloppy mount options * -U uuid * -V --version * --no-canonicalize * *---------------------------------------------------------------------- * what do we do with these * -l list? * -L